假设我有三个类,一个抽象类,一个派生类和一个包含派生类的类。
class Parent {
public:
Parent();
void FunctionOne() { cout << "error"; }
void FunctionTwo() = 0;
}
class Child : public Parent {
public:
Child();
void FunctionOne() { cout << "implement function one" ;}
void FunctionTwo() { cout << "implement function two" ;}
}
class Execute{
public:
Execute(Parent& newparent) : parent(newparent) ;
Execute& operator=(const Execute& in) {
parent = in.parent;
Run() { parent.functionOne(); parent.functionTwo(); }
private:
Parent& parent;
}
当我创建我的对象时执行一切都很好。
Excecute execute( Child );
execute.run();
输出:“执行功能一”“执行功能二”
问题在于,当我将它添加到向量时,正在复制Execute,这是复制Parent,但不是将Child复制到父级并使用多态,而是复制一个抽象类,我的输出是“错误”,我的程序崩溃了。
vector<Execute> list;
list.push_back( Execute( Child ) );
list[0].run(); // ERROR
是否需要复制引用以便复制Child类?我需要切换到指针吗?问题是,由于正在复制Execute,我没有一种简单的方法来管理删除指向Child的指针。我不能使用Boost或shared_ptr&lt;&gt;在这台机器上。
我将遗产添加到我的帖子中抱歉将其遗漏。我想我用Excecute execute(Child)解决了这个问题;我道歉,我试图简化问题以使其理解,并可能引入了一些微妙的错误。你能帮我解决原来的问题吗?
答案 0 :(得分:0)
首先,您要将对临时的引用存储在类中。一旦超出当前范围,您对该Execute
实例所做的任何事情都将在无效的引用上运行。
解决此问题:
class Execute
{
public:
Execute(Parent* newparent) : parent(newparent) {}
Execute(const Execute& e) : parent(e.parent) {} // for the rule of 3
~Execute() {} // empty destructor - since you didn't create it, you shouldn't delete it
Execute& operator=(const Execute& in)
{
parent = in.parent;
return *this;
}
Run()
{
parent.functionOne();
parent.functionTwo();
}
private:
Parent* parent;
};
然后,当你使用它时:
Parent* p = new Child();
// to show the scoping doesn't destroy p
{
Execute e(p);
e.Run();
}
delete p;
您可以在任何容器中传递Execute
个实例,并且不会使另一个实例的有效parent
成员无效。但是当你完成它们之后,你必须自己清理它们。
答案 1 :(得分:0)
如果修复了所有错误并将函数声明为虚拟并且可以编译代码,则行为符合预期:
implement function oneimplement function two
正如您所提到的,parent是对某些“原始”对象的引用。此对象必须动态分配或全局或自动,但比Execute / vector长。或者您可以将父级更改为普通成员变量,而不是引用。
Child c;
vector<Execute> list;
list.push_back( Execute( c ) );
list[0].Run();