我的C ++程序中有2个对象,都来自同一个父类: A类和B类都扩展了类基础。
是否可以使用A类创建一个对象,然后在程序中稍后将其更改为B类?
答案 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;
}
这非常难看,如果A
和B
没有完全相同的内存布局,则无法正常工作。如果您需要a
和b
成为同一个对象,则此方法有效。如果你不介意它们是不同的对象并且驻留在内存中的不同位置,那么你可以在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
类型的指针,该指针可以包含对A
或B
的引用。
将所有内容整合在一起的示例;
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();
}
如果您感到困惑,请查看虚函数并转换构造函数。