如果不在纯虚拟基类中创建显式函数,就无法完成复制构造吗?
我的目标是对一个类进行深度复制,但虚拟类造成了麻烦。
#include<iostream>
using namespace std;
class Vir//pure virtual class
{
public:
virtual void hi()=0;
};
class Handler:public Vir
{
public:
int i;
Handler() {}
Handler(int val):i(val) {}
void hi() {cout<<"Value of i="<<i<<endl;}
int getI() const {return i;}
void setI(int j) {i=j;}
};
class ControlPanel
{
public:
Vir *v;
ControlPanel(const ControlPanel& c)//copy constructor
{
v=new Handler;
v->setI(c.getI());
}
int getI()const {return v->getI();}
void initialize() {v=new Handler(10);}
void hi() {v->hi();}
ControlPanel() {}
~ControlPanel() {delete v;}
};
int main()
{
ControlPanel cc;
cc.initialize();
cc.hi();
ControlPanel bb(cc);//copying cc into bb
}
编译错误消息:
test.cpp: In copy constructor ‘ControlPanel::ControlPanel(const ControlPanel&)’:
test.cpp:28: error: ‘class Vir’ has no member named ‘setI’
test.cpp: In member function ‘int ControlPanel::getI() const’:
test.cpp:30: error: ‘class Vir’ has no member named ‘getI’
我计划有更多的 Handler 类(如 Handler1、Handler2 等),它们继承自 Vir,并将有自己独特的成员(如 float a; 或 double b; 等)。所以对我来说保留所有的吸气剂和吸气剂是没有意义的。 Vir 类中所有 Handler 类的 setter 函数。我想将 getter 和 setter 方法保留在 Handler 类中,因为这些成员对于 Handler 类来说是唯一的。 编译器不允许我这样做。帮助?
My objective is to do a deep copy of a class, but a virtual class is causing trouble.
#include<iostream>
using namespace std;
class Vir//pure virtual class
{
public:
virtual void hi()=0;
};
class Handler:public Vir
{
public:
int i;
Handler() {}
Handler(int val):i(val) {}
void hi() {cout<<"Value of i="<<i<<endl;}
int getI() const {return i;}
void setI(int j) {i=j;}
};
class ControlPanel
{
public:
Vir *v;
ControlPanel(const ControlPanel& c)//copy constructor
{
v=new Handler;
v->setI(c.getI());
}
int getI()const {return v->getI();}
void initialize() {v=new Handler(10);}
void hi() {v->hi();}
ControlPanel() {}
~ControlPanel() {delete v;}
};
int main()
{
ControlPanel cc;
cc.initialize();
cc.hi();
ControlPanel bb(cc);//copying cc into bb
}
The compilation error message:
test.cpp: In copy constructor ‘ControlPanel::ControlPanel(const ControlPanel&)’:
test.cpp:28: error: ‘class Vir’ has no member named ‘setI’
test.cpp: In member function ‘int ControlPanel::getI() const’:
test.cpp:30: error: ‘class Vir’ has no member named ‘getI’
I plan to have plenty more Handler classes (like Handler1, Handler2 etc) which inherit from Vir and will have their own unique members (like float a; or double b; etc). So it doesn't make sense for me to keep all the getter & setter functions of all Handler classes in the Vir class. I want to keep my getter and setter methods in the Handler classes because the members are unique to the Handler classes.
The compiler is not allowing me to do so. Help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
也许我遗漏了一些东西,但是在
Vir
上使用虚拟clone
方法不是更好吗?这意味着您可以避免在您自己的答案中概述的ControlPanel
复制构造函数中进行令人讨厌的转换。这与 @Andrew Aylett 在 他的答案使用了重复
而不是克隆
。在
Handler
中实现的类似的东西要
注意协变返回类型的使用,即
Handler::clone
允许返回一个Handler*
而不仅仅是一个Vir*
并且仍然是Vir::clone
的有效覆盖。这使得
ControlPanel
复制构造函数变得简单Maybe I am missing something but would you not be better with a virtual
clone
method onVir
? This means you can avoid the nasty cast in theControlPanel
copy constructor outlined in your own answer. This is the same as @Andrew Aylett suggests in his answer withduplicate
being used instead ofclone
.Something like
which is implemented in
Handler
to beNote the use of the covariant return type i.e.
Handler::clone
is allowed to return aHandler*
rather than just aVir*
and still be a valid override ofVir::clone
.This makes the
ControlPanel
copy constructor simply将
duplicate()
函数添加到您的抽象类中,该函数(在每个派生类中)创建一个具有正确值的新实例并返回它。或者,考虑使用copyFrom(Abs other)
函数,该函数会进行检查以确保您从正确的类型进行复制,如果是,则将字段复制出来。一般来说,如果您的 ControlPanel 类具有对 Abs 对象的引用,则它不应该尝试通过检查具体的 Handler 对象来进行复制,而应该将复制传递给该对象上的虚拟函数。
Add a
duplicate()
function to your abstract class, which (in each derived class) creates a new instance with the right values and returns it. Alternatively, consider acopyFrom(Abs other)
function which checks to ensure that you're copying from the correct type and if so, copies the fields out.In general, if your ControlPanel class has a reference to an Abs object, it shouldn't be trying to do its duplication by inspecting the concrete Handler object, it should be passing the duplication off to a virtual function on that object.
为什么编译器会允许你这样做?这些方法不在该接口上。
您可以使用工厂模式来创建您的
Vir
,以避免将所有构造函数添加到Vir
的接口中。您还应该考虑使用 RAII 来避免使用initialize() 风格的函数。Why would the compiler allow you? Those methods are not on that interface.
You could use the Factory Pattern to create your
Vir
, to avoid having to add all of the constructors toVir
's interface. You should also consider using RAII to avoid initialize() style functions.将
Vir *v
更改为Handler *v;
并查看您的代码是否可以编译。您的类
Vir
未声明/定义setI()
和getI()
成员函数。或者将
Vir
定义为Change
Vir *v
toHandler *v;
and see whether your code compiles or not.Your class
Vir
doesn't declare/definesetI()
andgetI()
member functions.Or define
Vir
as您必须在
Vir
中将getI
和setI
定义为(纯)虚拟,以使它们可以通过子类访问。没有办法解决这个问题。You have to define
getI
andsetI
as (pure) virtual inVir
to make them accessible via subclasses. No way around this.正如史蒂夫所建议的,我正在回答我自己的问题,因为一位朋友给了我一个解决方案。希望这对任何有如何在 C++ 中进行深度复制(其中虚拟类可能是一个障碍)问题的人有所帮助。希望有人觉得这很有用。
As Steve suggested, I'm answering my own question coz a friend gave me a solution. Hope this would be of help to anyone who has the question of how to do a Deep copy in C++ where a virtual class may be a roadblock. Hope someone finds this useful.