我可以在C ++中在运行时更改对象的类型

时间:2015-05-04 20:40:54

标签: c++ object

我的C ++程序中有2个对象,都来自同一个父类: A类和B类都扩展了类基础。

是否可以使用A类创建一个对象,然后在程序中稍后将其更改为B类?

3 个答案:

答案 0 :(得分:2)

以下代码有效:

#include <iostream>

class Base {};
struct A : public Base {int a;};
struct B : public Base {int b;};

int main()
{
  A *a = new A();
  a->a = 1;
  B *b = reinterpret_cast<B *>(a);
  std::cout << b->b << std::endl; 

  return 0;
}

这非常难看,如果AB没有完全相同的内存布局,则无法正常工作。如果您需要ab成为同一个对象,则此方法有效。如果你不介意它们是不同的对象并且驻留在内存中的不同位置,那么你可以在B中编写一个接收类型为A的对象或转换运算符的构造函数。

这听起来像XY Problem的典型例子,可能存在一个更优雅的解决方案来解决您的实际问题。

答案 1 :(得分:1)

简短的回答,没有。您无法安全地从A转换为B或B转换为A.您可以安全地转换为基类,因为A IS_A基类和B IS_A基类,但A而不是B,反之亦然。没有便携或安全的方法来做到这一点。虽然你的编译器可能会让你这样做,虽然看起来可行,但是以这种方式在不相关的类之间进行转换的结果是未定义的。

顺便说一下,没有理由不添加强制转换构造函数来允许从B构造A,反之亦然。那将是非常安全的。您只需使用A的成员初始化B的成员,反之亦然。任何不常见的成员,你可能需要处理它们,可能是指定它们的默认值。

答案 2 :(得分:1)

正如其他人所说,不,你不能这样做......技术上。实际上,您可以通过转换构造函数和虚函数来实现此效果。

如果您将转换构造函数从A编写为B,将B编写为A:

A::A(B convertFrom); // Convert from B to A
B::B(A convertFrom); // Convert from A to B

你将每个类的基本部分都虚拟化:

class base
{
    virutal void baseClassFunction();
};
class A
{
    virtual void baseClassFunction()
    {
        // Do things for A
    }
};
Class B
{
    virtual void baseClassFunction()
    {
        // Do things for B
    }
}

然后,您只需创建一个base类型的指针,该指针可以包含对AB的引用。

将所有内容整合在一起的示例;

int main()
{
    base *ptr = new A();
    bool needs_to_be_B;
    ...
    // Program logic
    ptr->baseClassFunction();
    ...
    if(needs_to_be_B)
    {
        base *tmp = new B(*ptr);
        delete ptr;
        ptr = tmp;
        delete tmp;
    }
    // ptr is now a B
    ptr->baseClassFunction();
}

如果您感到困惑,请查看虚函数并转换构造函数。