【问题标题】:Cast one derrived class to another without changing base class将一个派生类转换为另一个派生类而不更改基类
【发布时间】:2013-04-05 21:05:18
【问题描述】:

我有几个子类都有相同的父类。每个子类都可以使用父对象中包含的一些数据来构造。我想使用基础对象中包含的信息将一个孩子变成另一个孩子(不修改基础对象)。

目前它的实现如下例所示:

#include <iostream>

using namespace std;

class Data {};
class base
{
public:
    base()  {}
    base(Data input) : data(input)  {}
    virtual ~base() {   cout << "Deleting :" << this->name() << endl;   }
    template<class T> static base* CastToDerrived(base* object)
    {
        T* output = new T(object->data);
        delete object;
        return output;
    }
    virtual const char* name()  {return "base";}
    Data data;
};

class derrived1 : public base
{
public:
    derrived1() {}

    derrived1(Data input): base(input){}
    ~derrived1(){cout << "Deleting :" << this->name() << endl;}
    const char* name(){return "derrived1";}
};

class derrived2 : public base
{
public:
    derrived2(){}
    derrived2(Data input): base(input){}
    ~derrived2(){cout << "Deleting :\t" << this->name() << endl;}
    const char* name(){return "derrived2";}
};

int main(int argc, char *argv[])
{
    base* object = new derrived1();
    cout << "Created :\t"<<object->name()<<endl;
    object = base::CastToDerrived<derrived2>(object);
    cout << "Casted to :\t"<<object->name()<<endl;
}

哪些输出:

Created :   derrived1
Deleting :derrived1
Deleting :base
Casted to : derrived2

但是,这需要销毁并再次创建基类,我想避免这种情况 - 我想销毁 derrived1,使用 base 构造 derrived2,但保持基类完好无损。最好的方法是什么?

(派生类有好几个,基类提供了共同的接口,以后会在不修改基类的情况下添加一些派生类)。

【问题讨论】:

  • 所以你想移动基础对象?
  • 是的,我想移动它,但是我需要销毁一个孩子并使用基础对象创建另一个
  • 不要使用继承而是使用组合!你在你的类周围移动一个指向基类实现的指针,它永远不会被破坏(因为你保留了一个引用计数器)。
  • @Adriano,是的,这可以工作,但是基类为所有孩子提供了接口——通过继承,我可以为所有孩子及其接口使用指向基类的指针,并添加新的孩子而不修改使用它们的代码,我将如何使用组合来做到这一点?
  • @IlyaKobelevskiy,您可以让基类只保存一个指向包含所有“基”字段的结构的指针。这样您就可以将该结构的所有权从一个对象转移到另一个对象,而不会失去多态性的好处。

标签: c++ inheritance casting type-conversion


【解决方案1】:

你不能销毁派生类而保留基类,因为它是同一个实例。 我们可以使用以下代码来演示这一点

#include <iostream>

using namespace std;

class Data {};
class base
{
public:
    base()
    {
        printf("base pointer = %08X\n", this);
    }
};

class derrived1 : public base
{
public:
    derrived1()
    {
        printf("derrived1 pointer = %08X\n", this);
    }
};

int main(int argc, char *argv[])
{
    base* object = new derrived1();
    delete object;
    return 0;
}

输出将显示 base an derived1 是同一个指针 另一方面,您使用一些棘手的代码来实现您想要的。 这个想法是使用指向 Data 类的指针而不是变量。 您的代码将如下所示

#include <iostream>

using namespace std;

class Data {};
class base
{
public:
    base(){data = new Data}
    base(Data* input) : data(input)  {}
    virtual ~base() {   cout << "Deleting :" << this->name() << endl;   }
    template<class T> static base* CastToDerrived(base* object)
    {
        T* output = new T(object->data);
        delete object; 
        return output;
    }
    virtual const char* name()  {return "base";}
    Data* data;
};

class derrived1 : public base
{
public:
    derrived1() {}

    derrived1(Data* input): base(input){}
    ~derrived1(){cout << "Deleting :" << this->name() << endl;}
    const char* name(){return "derrived1";}
};

class derrived2 : public base
{
public:
    derrived2(){}
    derrived2(Data* input): base(input){}
    ~derrived2(){cout << "Deleting :\t" << this->name() << endl;}
    const char* name(){return "derrived2";}
};

int main(int argc, char *argv[])
{
    base* object = new derrived1();
    cout << "Created :\t"<<object->name()<<endl;
    object = base::CastToDerrived<derrived2>(object);
    cout << "Casted to :\t"<<object->name()<<endl;
}

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 2016-12-12
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 2013-11-17
    相关资源
    最近更新 更多