我在这里的第一篇文章!我多年来一直使用这个网站作为参考,并找到常见问题的解决方案。不幸的是,我遇到的这个问题还没有在这里找到!所以这就是。我一直在研究一个项目。我的程序有几千行代码,所以我不会在这里发布。基本上,我有一个子类,我希望将父类更改为已在我的代码中的某个地方初始化的类。我不确定这是否可行,或者它是否是良好的代码实践。但我会让你们做出判断!这是我面临的问题:
#include <stdio.h>
class Base
public:
int data;
Base(int);
};
class Child : public Base
{
public:
Child(void);
void run(Base*);
};
Base::Base(int var)
{
data=var;
}
void Child::run(Base* base)
{
this = base //I know that you can create a reference to the parent class
//by casting this pointer to a Base pointer, but was wondering
//if you can do this the other way around.
printf("%d\n",Base::data);
}
int main()
{
Base* base1 = new Base(5);
Base* base2 = new Base(3);
Child one();
one.run(base1);
delete base1;
delete base2;
base1=0;
base2=0;
return 0;
}
因此,如果这个编译(它没有),它将输出类似5的东西,如果我将run方法参数更改为base2,它应该打印类似3.这可能吗?谢谢!
答案 0 :(得分:1)
你无法准确地做到你想要的,但你可以做类似的事情。如果父类具有复制构造函数,它允许您创建一个实例,该实例是另一个实例的副本,那么您可以使用该复制构造函数在构造子对象时创建父对象:
class Child : public Base
{
public:
Child(const Base &b) : Base(b) { ...}
现在您有一个Child
对象,其Base
部分与另一个Base
对象的部分相同。
答案 1 :(得分:0)
不,你不能做那样的事情。 This
是一个READ-ONLY指针。这条线
this = base;
会生成语法错误。
C ++中的基类是静态的。它们不能在运行时更改。
虽然,如果你的课程(基础课程和孩子课程)都没有虚拟功能,那么下面的工作将会起作用:
(Base&)*this = *base;
与此同时,我会劝阻你这样做。令人沮丧的原因是因为这样的代码很容易受到变化的影响。例如,如果将虚拟方法添加到任一类,则将覆盖VMT。这可能不适用于多重继承。在我使用MSVC的实验中,我注意到有时它会改变类的二进制布局中基类的顺序。
换句话说,如果您完全确定编译器使用的布局,则可以使用此方法。如果您确定编译器将来不会更改此布局。如果没有,最好避免这种情况。
正确的方法是创建一个特殊方法并按字段复制数据字段。
答案 2 :(得分:0)
将this
视为const。当您获得对基类的引用时,您很容易获得对子类的某个子集(部分)的引用;基类实例紧密绑定到整个类(在本例中为子类实例)。您可以指导如何初始化该基类(请参阅Ernest的响应),但您无法破坏该链接。
通常,类与基类的内存布局类似于:
[... |基类| ...... ...... ..)
它实际上是嵌入式的,而不是独立存在的(以下是不正常的,我甚至可以说它永远不会发生 - 但这是内部编译器的选择):
[... |引用基类| ...... ...... [独立基类实例]