具有类型转换的多态复制构造函数
我需要复制构造一个对象,同时将其类型更改为同一类层次结构成员的另一个类。我读过有关多态复制构造函数的内容,并(希望)理解其背后的想法。然而,我仍然不知道这种模式是否适用于我的情况,如果适用,如何实现它。我认为最好通过一个例子来展示我需要的东西。
有一个 Base
类和两个子类:Child1
和 Child2
。我需要基于 Child1
创建一个 Child2
类型的对象,即。最重要的是,我需要将 p_int
指向的对象从 Child1
复制到 Child2
。我写了一个简单的程序来说明它:
#include <iostream>
using namespace std;
class Base {
public:
Base() { p_int = new int; *p_int = 0; }
~Base() { delete p_int; }
virtual Base* clone() const = 0;
void setpInt(int val) { *p_int = val; }
void setInt(int val) { a = val; }
virtual void print() {
cout << "Base: ";
cout << (long)p_int << ":" << *p_int << " " << a << endl;
}
protected:
int* p_int;
int a;
};
class Child1 : public Base {
public:
Child1() {};
Child1(const Child1& child) {
p_int = new int (*child.p_int);
a = child.a + 1;
}
Base* clone() const { return new Child1(*this); }
void print() {
cout << "Child1: ";
cout << (long)p_int << ":" << *p_int << " " << a << endl;
}
};
class Child2 : public Base {
public:
Child2() {};
Child2(const Child2& child) {
p_int = new int (*child.p_int);
a = child.a + 1;
}
Base* clone() const { return new Child2(*this); }
void print() {
cout << "Child2: ";
cout << (long)p_int << ":" << *p_int << " " << a << endl;
}
};
int main() {
Child1* c1 = new Child1();
Child2* c2;
c1->setpInt(4);
c1->print();
c2 = (Child2*)c1->clone();
c2->print();
}
不幸的是,结果如下,即。没有类型转换:
Child1: 162611224:4 0
Child1: 162611272:4 1
我到底需要实现什么才能实现我所需要的?我开始认为我需要实现一种类型转换机制,而不是多态复制构造函数,但我已经很困惑了。
编辑:在此处询问后续
I need to copy-construct an object simultaneously changing it's type to another class being a member of the same class-hierarchy. I've read about polymorphic copy-constructors and (hopefully) understand the idea behind it. Yet, I still don't know if this pattern applies to my case and, if so, how to implement it. I think it's best if I show what I need on an example.
There is a Base
class and two child classes, Child1
and Child2
. I need to create an object of type Child2
basing on Child1
, ie. most of all, I need to copy the object p_int
is pointing to from Child1
to Child2
. I've written a simple program to illustrate it:
#include <iostream>
using namespace std;
class Base {
public:
Base() { p_int = new int; *p_int = 0; }
~Base() { delete p_int; }
virtual Base* clone() const = 0;
void setpInt(int val) { *p_int = val; }
void setInt(int val) { a = val; }
virtual void print() {
cout << "Base: ";
cout << (long)p_int << ":" << *p_int << " " << a << endl;
}
protected:
int* p_int;
int a;
};
class Child1 : public Base {
public:
Child1() {};
Child1(const Child1& child) {
p_int = new int (*child.p_int);
a = child.a + 1;
}
Base* clone() const { return new Child1(*this); }
void print() {
cout << "Child1: ";
cout << (long)p_int << ":" << *p_int << " " << a << endl;
}
};
class Child2 : public Base {
public:
Child2() {};
Child2(const Child2& child) {
p_int = new int (*child.p_int);
a = child.a + 1;
}
Base* clone() const { return new Child2(*this); }
void print() {
cout << "Child2: ";
cout << (long)p_int << ":" << *p_int << " " << a << endl;
}
};
int main() {
Child1* c1 = new Child1();
Child2* c2;
c1->setpInt(4);
c1->print();
c2 = (Child2*)c1->clone();
c2->print();
}
Unfortunately, the outcome is as below, ie. there is no type conversion:
Child1: 162611224:4 0
Child1: 162611272:4 1
What exactly do I need to implement, to be able to achieve what I need? I'm starting to think there is a type-conversion mechanism I need to implement rather than a polymorphic copy-constructor, but I'm confused already.
EDIT: Asked a follow up here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最简单的解决方案可能是实现一个以
Child1&
作为参数的Child2
构造函数。然后你可以简单地调用:Simplest solution would probably be to implement a
Child2
constructor taking aChild1&
as parameter. Then you could simply call:如果您只有 2 个子类,那么最简单的方法是创建一个转换构造函数:
如果您有多个 Child 类,并且需要从其中任何一个子类创建一个 Child2,那么您可以执行以下操作:
If you only have 2 child classes, then the easiest way is to create a conversion constructor:
If you have several Child classes, and you need to create a Child2 from any of them, then you could do something like this:
这是一个严重的错误,而 c 风格的转换隐藏了该错误。
如果您使用C++风格的强制转换,那么它不会隐藏该错误,并且您会知道它。在本例中,C++ 风格的转换为:
dynamic_cast
。用它来自己发现错误。从代码中可以清楚地看出,
c1-clone()
创建了c1
的克隆,其类型为Child1*
和clone( )
返回一个Base*
类型的指针(从Child1*
向上转换之后),您尝试向下转换为Child2*< /代码>。如果您使用正确的转换:
dynamic_cast
,则转换应该失败。Here is a serious bug, and the c-style cast hides the bug.
If you use C++-style cast, then it will not hide the bug, and you will know it. In this case, the C++-style cast is :
dynamic_cast
. Use it to discover the bug yourself.As it is clear from the code that
c1-clone()
creates a clone ofc1
whose type isChild1*
andclone()
returns a pointer of typeBase*
(after upcasting fromChild1*
), which you're trying to down-cast toChild2*
. The cast should fail if you use proper cast :dynamic_cast
.Clone() 模式允许您创建仅具有基引用的子类对象的有效副本/克隆,例如,在您的情况下,它允许您执行以下操作:
您可能需要的是“复制构造函数”允许您从基类复制,例如:
结果:
The clone() patterns allows you to create a valid copy/clone of the object of a child class having just the base reference, e.g. in your case it allows you to do the following:
What you could need is a "copy-constructor" that allows you to copy from a base class, e.g.:
Result: