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

C++ C++;:多态复制构造函数可以工作吗?,c++,copy-constructor,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

考虑:

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;
}

如果“新A(B1)”能够解析创建新的B副本并返回A?

,C++会被破坏吗?
这是否有用?

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

如果需要这样做,常用的习惯用法是使用
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;
}
对。没有

在不改变现有程序含义的情况下,有多种实现克隆的方法(例如,或多或少的标准克隆()方法、对象工厂的参数化变体、有无可配置依赖项注入),或者,当编译单元中已知派生类时,无法创建基类的实例

构造函数和析构函数足够复杂,初学者可以理解。给它们注入更多的复杂性是不明智的

new A(*b1)
已经有了意义,假设你有了适当的过载

如果它被赋予了不同的含义,你就必须提供另一种方式来获得另一种含义。考虑到已经有一种方法可以得到你想要的意义,这是毫无意义的:

new B(*b1)

猜猜看哪个更清晰。

你真正想要的是a,eduffy发布的是标准的阅读方式


还有。(免责声明:自我推销)

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

要回答您的问题,如果
newa(*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;
}

只是对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*

+1调用,则会更好,但我也会向类中添加一个虚拟析构函数;)这确实是一个思想实验。虽然这是实现虚拟副本构造函数的标准方法,但我很好奇为什么该语言没有提供标准化的方法来实现这一点。协变返回更好:B*B::Clone()感谢第二个链接,我喜欢这个概念,但第二个例子假设你先验地知道
b1
实际上是a
B
@user470379-绝对;我的观点不是说
new B(*b1)
是答案,而是
new A(*b1)
不能是答案。太棒了,但我不明白为什么它是有效的^^因为这些是协变返回类型。§ 10.3.7