抽象类层次结构和访问冲突

时间:2016-08-29 11:33:30

标签: c++

这背景是我试图重新考虑复杂的C ++应用程序。我已将下面的代码放在一起作为我正在使用的代码的精简版本(删除无关紧要的方法等)。我可能做了一些愚蠢的事情,因为我多年没有接触过C ++,但我可以看到......

我有以下课程

message_sink.h:

class IMessageSink
{
public:
    virtual ~IMessageSink() { };
    virtual void process(const Message& msg) = 0;
};

使用以下基类

model_base.h:

class Model : public virtual IMessageSink
{
public:
   Model(Tag a);

   virtual Model* makeA(Tag a) = 0;
   void reset();

private:
   friend class EM;

   const Tag _a;
   virtual void calculate(double lambda) = 0;
};

其中 model_base.cpp

Model::Model(Tag a) : _a(a) { }

void Model::reset()
{
   // ... some implementation
}

void Model::process(const Message msg)
{
    // ... some implementation
}

然后我继承了从基类

继承的以下类

model_m0.h:

class ModelM0 : public virtual Model
{
public:
    ModelM0(Tag a);        
    ModelM0* make(Tag a);

private:
    void calculate(double lambda);
};

model_m0.cpp:

ModelM0::ModelM0(Tag a) : Model(a) { }

ModelM0* ModelM0::make(Tag a)
{
   ModelM0* m = new ModelM0(a);
   m->reset();
   return m;
}

void ModelM0::calculate(double lambda)
{
    // Some code...
}

但问题出在哪里,我有另一个名为ModelM0Holder的类,这被定义为

model_m0_holder.h:

class ModelM0Holder : public IMessageSink
{
public:
    static ModelM0Holder* make(Tag a)
    {
        return new ModelM0Holder(a);
    }
    ModelM0Holder(Tag a);
    ~ModelM0Holder();
    void process(const Message& msg);

private:
    ModelM0* getModel(int line);
};

model_m0_holder.cpp:

ModelM0Holder::ModelM0Holder(Tag a) : _a(a) { } 

ModelM0Holder::~ModelM0Holder()
{
    // ... some implementation
}

void ModelM0Holder::process(const Message& msg)
{
    // ... some implementation
}

ModelM0* ModelM0Holder::getModel(int ag)
{
    ModelM0* m;
    m = m->make(_a); // Access Violation Exception.
    // ... 
}

当我致电ModelM0Holder::getModel时,我收到AccessViolationException,我无法调用此功能,为什么?

非常感谢你的时间。

2 个答案:

答案 0 :(得分:3)

ModelM0* m;

if (_period == tau::PERIOD_A)
    m = m->makeA(_newObsTag); // Access Violation Exception.
else
    m = m->makeB(_newObsTag);

您正尝试取消引用未初始化的指针m。这是一种未定义的行为。在不知道项目细节的情况下,很难说出应该如何解决这个问题。也许应该使用某种工厂。

答案 1 :(得分:1)

m->被酉化时,您无法m。这将访问随机内存位置(并导致转储)。

如果我理解您的代码意图正确,您可以makeAmakeB静态。

class ModelM0 : public virtual Model
{
public:
    . . .    
    static ModelM0* makeA(Tag newObsTag);
    static ModelM0* makeB(Tag newObsTag);
    . . .    
};

然后将getModel更改为:

    ModelM0* m;

    if (_period == tau::PERIOD_A)
        m = ModelM0::makeA(_newObsTag);
    else
        m = ModelM0::makeB(_newObsTag);