将一个派生类转换为另一个类,而不改变基类 [英] Cast one derrived class to another without changing base class
问题描述
我有几个子类都有相同的父。每个子类都可以使用父对象中包含的一些数据来构造。我想使用基础对象中包含的信息(而不修改基础对象)将一个孩子转换为另一个孩子。
目前它的实现如下例所示: / 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,但保持基类完好无损。什么是最好的方法呢?
删除: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屋!