我知道像这样的向下转换是行不通的.我需要一种可行的方法.这是我的问题:我从基类中得到了几个不同的派生类.我的第一个尝试是创建一个基类数组.程序必须选择(或多或少随机)不同的派生类.我曾尝试从基类转换到派生类,将它放在基类的数组中,但显然这不起作用.我真诚地希望采用另一种方法而不是简单地粘贴所有派生类的数组,因为可能会有相当多的派生类.有没有更好的方法来做到这一点,我只是在脑力训练?
如果您需要代码示例或更多信息,请告诉我.这对我来说都是有意义的,但现在已经很晚了,对其他人来说可能没有意义.
伙计们,非常感谢任何帮助.
Joh*_*itb 13
不明白你的意思.听起来像是按值存储对象,而你有一个数组Base
.这不起作用,因为只要您分配Derived,该对象将被转换为Base,并且对象的Derived部分被切掉.但我想你想要一个基数指针数组:
Base * bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i] = new Derived1;
else if(r == 1)
bases[i] = new Derived2;
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果你曾经使用过指针,你就会知道管理它们很麻烦,特别是传递并且不会丢失它们,因为你需要调用delete来释放内存并调用对象的析构函数.您可以使用shared_ptr,它将为您管理:
shared_ptr<Base> bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i].reset(new Derived1);
else if(r == 1)
bases[i].reset(new Derived2);
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以传递bases[x]
给另一个shared_ptr,它会注意到您有多个引用 - 如果对象的最后一个引用超出范围,它将自动调用.理想情况下,您还可以用std :: vector替换原始数组:
std::vector< shared_ptr<Base> > bases;
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases.push_back(shared_ptr<Base>(new Derived1));
else if(r == 1)
bases.push_back(shared_ptr<Base>(new Derived2));
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后你可以传递向量,不要丢失它的大小,你可以根据需要动态添加项目.使用获取向量的大小bases.size()
.在shared_ptr
这里阅读.
只有在绝对必要时才能从Base类转换为Derived类.通常,你想使用一种叫做的技术polymorphism
,这意味着你在基指针上调用一个函数,但它实际上会调用一个在派生类中定义的函数,具有相同的签名(名称和参数是相同的类型)并且被称为到override
它.阅读维基百科上关于它的文章.如果你真的需要强制转换,你可以这样做一个原始指针:
Derived1 * d = &dynamic_cast<Derived1&>(*bases[x]);
Run Code Online (Sandbox Code Playgroud)
使用dynamic_cast可以确保,当您转换为错误的类型时(即,您投射的类型不是创建并分配给基指针的类型),您将获得操作员抛出的异常.对于shared_ptr案例,也有一些方法:
shared_ptr<Derived1> d = dynamic_pointer_cast<Derived1>(bases[x]);
if(d) {
// conversion successful, it pointed to a derived. d and bases[x] point still
// to the same object, thus share it.
}
Run Code Online (Sandbox Code Playgroud)
Leo*_*Hat 10
在大多数情况下,从基类转换为派生类是一种糟糕的代码味道.
通过使用虚拟方法,多态性是一种更好的方法.
调用代码应使用基类指针调用方法,允许将其分派到派生类中的相应实现.
我知道这是一个相当通用的答案,但如果没有一些代码片段作为示例,很难在您的情况下推荐更具体的答案.