用C ++思考练习

时间:2014-06-12 18:43:09

标签: c++

我正在尝试这样做:

  

创建一个包含clone()函数的基类,该函数返回一个   指向当前对象副本的指针。派生出两个子类   override clone()返回其特定类型的副本。在主要(   ),创建和转发两个派生类型的对象,然后调用   每个clone()并验证克隆的副本是否正确   亚型。尝试使用clone()函数,以便返回   基类型,然后尝试返回确切的派生类型。你能   想一想后一种方法是必要的情况吗?

我的尝试:

#include <cstdlib>
#include <iostream>
using namespace std;

class Base {
public:

    virtual Base* clone() {
        Base copy = *this;
        return &copy;
    }

    void show() {
        cout << "BASE\n";

    }

};

class D1 : public Base {
public:

    Base* clone() {
        cout << "OVEr\n";

        D1 copy = *this;
        D1* clo = dynamic_cast<D1*> (&copy);

        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 *对象。

2 个答案:

答案 0 :(得分:2)

您的代码在这里:

virtual Base* clone() {
    Base copy = *this;
    return &copy;
}

不是你想要的。这将返回在结束}之后超出范围的局部变量的地址。您需要做的是使用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 *对象。

查找一个名为协变返回类型的概念,这正是您要问的内容。