使用对派生对象的引用复制类

时间:2013-09-24 17:13:13

标签: c++ polymorphism

假设我有三个类,一个抽象类,一个派生类和一个包含派生类的类。

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)解决了这个问题;我道歉,我试图简化问题以使其理解,并可能引入了一些微妙的错误。你能帮我解决原来的问题吗?

2 个答案:

答案 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();