2009-06-20 137 views
6

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

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

将c + +,如果被打破的 “新A(B1)” 是能够解决创造一个新型B拷贝并返回一个

这会甚至有用吗?

回答

19

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

如果你需要做到这一点,常见的成语是有一个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; 
} 
+5

+1叫,但我也想补充一个虚拟析构函数的类;) – 2009-06-20 14:00:30

+0

这确实是一个思想实验。虽然这是实现虚拟拷贝构造函数的标准方式,但我很好奇为什么这种语言没有提供一种标准化的方式来实现这一点。 – 0xC0DEFACE 2009-06-21 12:41:03

+0

协变回报更好:B * B :: Clone() – 2018-01-24 17:11:09

0

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

构造函数和析构函数对于初学者来说是相当复杂的。向他们注入更复杂的东西是不明智的。

1

表达

new A(*b1) 

已经有一个意义,假设你有适当的过载。

如果给出了不同的含义,则必须提供另一种方式来获得其他含义。这是一种毫无意义的因为已经有办法得到你想要的含义:

new B(*b1) 

你猜这是更清晰的阅读。

+1

但第二个例子假定你知道事实上`b1`实际上是`B`。 – user470379 2011-01-19 20:48:19

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