C ++:多态复制构造函数可以工作吗?

时间:2009-06-20 13:29:07

标签: c++ copy-constructor

考虑:

class A
{
public:
    A( int val ) : m_ValA( val ) {}
    A( const A& rhs ) {}
    int m_ValA;
};

class B : public A
{
public:
    B( int val4A, int val4B ) : A( val4A ), m_ValB( val4B ) {}
    B( const B& rhs ) : A( rhs ), m_ValB( rhs.m_ValB ) {}
    int m_ValB;
};

int main()
{
    A* b1 = new B( 1, 2 );
    A* b2 = new A( *b1 ); // ERROR...but what if it could work?
    return 0;
}

如果“new A( b1)”能够解析为创建新的B副本并返回A ,C ++会被破坏吗?

这会有用吗?

6 个答案:

答案 0 :(得分:20)

您是否需要此功能,或者这只是一个思想实验?

如果你需要这样做,常见的习惯用法是Clone方法:

class A
{
public:
    A( int val ) : m_ValA( val ) {}
    A( const A& rhs ) {}
    virtual A *Clone () = 0;
    int m_ValA;
};

class B : public A
{
public:
    B( int val4A, int val4B ) : A( val4A ), m_ValB( val4B ) {}
    B( const B& rhs ) : A( rhs ), m_ValB( rhs.m_ValB ) {}
    A *Clone() { return new B(*this); }
    int m_ValB;
};

int main()
{
    A* b1 = new B( 1, 2 );
    A* b2 = b1->Clone();
    return 0;
}

答案 1 :(得分:4)

你真正想要的是virtual copy constructor,而eduffy发布的是标准的做法。

还有clever ways of doing it with templates。 (免责声明:自我推销)

答案 2 :(得分:2)

eduffy对答案的一小部分补充: 而不是

class B : public A {
  ...
  A *Clone() { return new B(*this); } 
  ...

};

你可以这样声明:

class B : public A {
  ...
  B *Clone() { return new B(*this); } // note: returning B *
  ...

};

它仍被视为虚拟A::Clone();的有效覆盖,如果直接通过B *

进行调用则会更好

答案 3 :(得分:1)

表达式

new A(*b1)

已经有了意义,假设你有适当的超载。

如果给出了不同的含义,你必须提供另一种方法来获得另一种含义。鉴于已经有办法获得你想要的意思,这有点毫无意义:

new B(*b1)

猜猜哪个更清楚。

答案 4 :(得分:0)

是。没有。

有许多方法可以实现克隆(例如,或多或少的标准clone()方法,对象工厂的参数化变体,有或没有可配置的依赖注入),而不改变现有程序的含义,或者使其无法实现在编译单元中已知派生类时创建基类的实例。

构造函数和析构函数对于初学者来说足够复杂。向它们注入更多复杂性是不明智的。

答案 5 :(得分:0)

如上所述,有许多方法可以实现这一点。

如果new A( *b1 )返回了B的新实例,则回答您的问题,那么这将不起作用。

int main()
{
    A* b1 = new B( 1, 2 );
    A a( *b1 ); // What size would 'a' be if it was polymorphicly constructed?
    return 0;
}