将一个派生类转换为另一个类,而不改变基类 [英] Cast one derrived class to another without changing base class

查看:147
本文介绍了将一个派生类转换为另一个类,而不改变基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

  #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(){returnbase;}
数据数据;
};

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

derrived1(数据输入):base ){}
〜derrived1(){cout<< Deleting:<< this-> name()<< endl;}
const char * name(){returnderrived1;}
};

class derrived2:public base
{
public:
derrived2(){}
derrived2(数据输入):base b $ b〜derrived2(){cout< Deleting:\t<< this-> name()<< endl;}
const char * name(){returnderrived2;}
};

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;
}

哪些输出:

 创建:derrived1 
删除:derrived1
删除:base
强制转换为:derrived2


(有几个派生类,基类为所有类提供通用接口,一些派生类稍后将添加,而不修改基类)。

解决方案

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

  #include< iostream> 

using namespace std;

class Data {};
class base
{
public:
base()
{
printf(base pointer =%08X \\\
,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;
}

输出将显示一个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(){returnbase;}
data * data;
};

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

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

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

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;
}

我希望这会有所帮助。


I have several child classes all having same parent. Each child class can be constructed using some data that is contained in parent object. I would like to cast one child to be another child using info contained in base object (without modifying base object).

Currently it is implemented as illustrated in following example:

#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;
}

Which outputs:

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

However, this requires base class to be destroyed and created again, which I would like to avoid - I would like to destroy derrived1, use base to construct derrived2, but keep the base class intact. What is the best way to do that?

(There are several derived classes, base class provides common interface for all, some derived class will be added later without modifying the base).

解决方案

you can't destroy the derived class an keep the base class because it's the same instance. we can demonstrate this using the folowing code

#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;
}

the output will show that base an derived1 is the same pointer on the other hand you use some tricky code to achieve what you want. the idea is to use a pointer to Data class instead of a variable. your code will become then as folowing

#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;
}

i wish this will help.

这篇关于将一个派生类转换为另一个类,而不改变基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆