抽象类层次结构与访问冲突 背景是我试图重新构造一个复杂的C++应用程序。我已经将下面的代码整合为我正在使用的代码的精简版本(删除不相关的方法等)。我可能做一些愚蠢的事情,因为我几年没有接触过C++,但我能看到什么……p>
我有以下课程 消息\u sink.h:抽象类层次结构与访问冲突 背景是我试图重新构造一个复杂的C++应用程序。我已经将下面的代码整合为我正在使用的代码的精简版本(删除不相关的方法等)。我可能做一些愚蠢的事情,因为我几年没有接触过C++,但我能看到什么……p>,c++,C++,我有以下课程 消息\u sink.h: class IMessageSink { public: virtual ~IMessageSink() { }; virtual void process(const Message& msg) = 0; }; class Model : public virtual IMessageSink { public: Model(Tag a); virtual Model* makeA(Tag a) = 0; v
class IMessageSink
{
public:
virtual ~IMessageSink() { };
virtual void process(const Message& msg) = 0;
};
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;
};
class ModelM0 : public virtual Model
{
public:
ModelM0(Tag a);
ModelM0* make(Tag a);
private:
void calculate(double lambda);
};
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...
}
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);
};
使用以下基类
型号基础.h:
class IMessageSink
{
public:
virtual ~IMessageSink() { };
virtual void process(const Message& msg) = 0;
};
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;
};
class ModelM0 : public virtual Model
{
public:
ModelM0(Tag a);
ModelM0* make(Tag a);
private:
void calculate(double lambda);
};
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...
}
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);
};
其中模型基础.cpp为
Model::Model(Tag a) : _a(a) { }
void Model::reset()
{
// ... some implementation
}
void Model::process(const Message msg)
{
// ... some implementation
}
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.
// ...
}
然后我从基类继承了以下类
型号\u m0.h:
class IMessageSink
{
public:
virtual ~IMessageSink() { };
virtual void process(const Message& msg) = 0;
};
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;
};
class ModelM0 : public virtual Model
{
public:
ModelM0(Tag a);
ModelM0* make(Tag a);
private:
void calculate(double lambda);
};
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...
}
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);
};
型号0.cpp:
class IMessageSink
{
public:
virtual ~IMessageSink() { };
virtual void process(const Message& msg) = 0;
};
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;
};
class ModelM0 : public virtual Model
{
public:
ModelM0(Tag a);
ModelM0* make(Tag a);
private:
void calculate(double lambda);
};
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...
}
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);
};
但问题就在这里,我有另一个类叫做ModelM0Holder
,定义为
型号m0\U支架。h:
class IMessageSink
{
public:
virtual ~IMessageSink() { };
virtual void process(const Message& msg) = 0;
};
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;
};
class ModelM0 : public virtual Model
{
public:
ModelM0(Tag a);
ModelM0* make(Tag a);
private:
void calculate(double lambda);
};
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...
}
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);
};
和型号m0\U支架。cpp:为
Model::Model(Tag a) : _a(a) { }
void Model::reset()
{
// ... some implementation
}
void Model::process(const Message msg)
{
// ... some implementation
}
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
,我不能调用这个函数,为什么
非常感谢您抽出时间
ModelM0* m;
if (_period == tau::PERIOD_A)
m = m->makeA(_newObsTag); // Access Violation Exception.
else
m = m->makeB(_newObsTag);
您正试图取消对未初始化指针m
的引用。这是一种未定义的行为。在不了解项目详细信息的情况下,很难判断应该如何解决这个问题。也许应该用某种工厂来代替
您正试图取消对未初始化指针
m
的引用。这是一种未定义的行为。在不了解项目详细信息的情况下,很难判断应该如何解决这个问题。也许应该使用某种工厂来代替。当m
被单元化时,您不能执行m->
。这将访问随机内存位置(并导致转储)
如果我正确理解了代码的意图,您可以将makeA
和makeB
设置为静态
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);
当
m
被单位化时,您不能执行m->
。这将访问随机内存位置(并导致转储)
如果我正确理解了代码的意图,您可以将makeA
和makeB
设置为静态
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);
你删掉了太多相关信息,无法确定。但是
ModeM0::getModel()
似乎没有做任何事情来阻止对i
的解引用,即使i
是一个结束迭代器。在取消引用之前,它也不会初始化m
。这两者都会导致未定义的行为。另外,IMessageSink::process()
通过引用接受参数,但是Model::process()
通过值接受参数-这意味着它隐藏而不是覆盖继承的版本。您在调用m->makeA()
时使用的是unitializedm
。可能应该是一个静态方法,因此ModelM0::makeA()
,但它不能是虚拟的。同样适用于makeB
。Peter提出了一些有效的观点,这些事情可能不是你个人的问题,但结合起来可能会像你看到的一样。感谢你的时间伙伴们。你删掉了太多相关信息,无法确定。但是ModeM0::getModel()
似乎没有做任何事情来阻止对i
的解引用,即使i
是一个结束迭代器。在取消引用之前,它也不会初始化m
。这两者都会导致未定义的行为。另外,IMessageSink::process()
通过引用接受参数,但是Model::process()
通过值接受参数-这意味着它隐藏而不是覆盖继承的版本。您在调用m->makeA()
时使用的是unitializedm
。可能应该是一个静态方法,因此ModelM0::makeA()
,但它不能是虚拟的。对于makeB
,Peter提出了一些有效的观点,这些东西可能不是单独的问题,但结合起来可能会像你所看到的一样感谢你的时间伙伴们,非常感谢。在重构之前,我有makeA
和makeB
静态,我只是尝试过了。这显然是问题所在-永远不要编写宿醉代码…在重构之前,我有makeA
和makeB
静态代码,我只是尝试过了。这显然是问题所在-永远不要给宿醉者编码。。。