我正在尝试这样做:
创建一个包含clone()函数的基类,该函数返回一个 指向当前对象副本的指针。派生出两个子类 override clone()返回其特定类型的副本。在主要( ),创建和转发两个派生类型的对象,然后调用 每个clone()并验证克隆的副本是否正确 亚型。尝试使用clone()函数,以便返回 基类型,然后尝试返回确切的派生类型。你能 想一想后一种方法是必要的情况吗?
我的尝试:
#include <cstdlib>
#include <iostream>
using namespace std;
class Base {
public:
virtual Base* clone() {
Base copy = *this;
return ©
}
void show() {
cout << "BASE\n";
}
};
class D1 : public Base {
public:
Base* clone() {
cout << "OVEr\n";
D1 copy = *this;
D1* clo = dynamic_cast<D1*> (©);
return clo;
}
void show() {
cout << "D1\n";
}
};
int main(int argc, char** argv) {
D1 d1;
Base& ptr1 = d1;
(ptr1.clone())->show();
return 0;
}
我的问题是什么?如果我们应该覆盖虚拟Base * clone(),我无法想象如何返回D1 *对象。
答案 0 :(得分:2)
您的代码在这里:
virtual Base* clone() {
Base copy = *this;
return ©
}
不是你想要的。这将返回在结束}
之后超出范围的局部变量的地址。您需要做的是使用new
关键字动态分配克隆:
virtual Base* clone() {
Base* copy = new Base(*this); // NOTE: This calls a copy constructor
return copy;
}
如果使用new
动态分配对象,则还必须记住使用delete
解除分配对象,否则会造成内存泄漏。
要覆盖克隆功能,您应该使用override
关键字来捕获匹配功能签名的错误。您还要再次重复返回指向超出范围的局部变量的指针的错误。
upcast意味着简单地将派生类型视为其父类型,通过基类型指针或引用引用它,如下所示:
Base* ptr = new D1;
您的clone()函数中不需要dynamic_cast
任何内容。我假设您的意图是使用来自某个外部函数(IE dynamic_cast
)的main()
进行检查,以确保您的Base*
指针实际上指向D1
对象
答案 1 :(得分:1)
我的问题是什么
作者希望您动态地从免费存储创建一个对象,并返回指向该对象的指针。虽然你有一个派生类型指针,但由于它的向上投射,这将按预期工作。
如果我们应该覆盖虚拟Base * clone(),我无法想象如何返回D1 *对象。
查找一个名为协变返回类型的概念,这正是您要问的内容。