2012-07-28 112 views
0

我的第一篇文章在这里!我多年来一直在使用这个网站作为参考,并找到常见问题的解决方案。不幸的是,我遇到的这个问题还没有在这里找到!所以在这里。我一直在做一段时间的项目。我的程序有几千行代码,所以我不会在这里发布。基本上,我有一个我希望将父类更改为已在我的代码中已经初始化的子类。我不确定这是否可行,或者是否是良好的代码练习。但是我会让你们成为那个评委!这里是我面临的问题:C++更改子类中的父类

#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; 
} 

因此,如果此编译(这不)会outputt像5,如果我改变运行参数传递给BASE2它应打印像3.这是可能?谢谢!

回答

0

不,你不能做那样的事情。 This是只读指针。该行

this = base; 

将生成语法错误。

C++中的基类是静态的。它们不能在运行时更改。

尽管如此,如果你的类(包括底座和孩子)没有虚函数,该follwoing将工作:

(Base&)*this = *base; 

同时我会阻止你这样做。令人沮丧的原因是因为这样的代码在变化时会非常脆弱。例如,如果将虚拟方法添加到任何一个类中,则VMT将被覆盖。这可能不适用于多重继承。在我使用MSVC的实验中,我注意到有时它会改变类的二进制布局中基类的顺序。

换句话说,如果你是绝对肯定的编译器使用的布局可以使用。如果您确定编译器将来不会更改此布局。如果没有,最好避免这一点。

正确的做法是创建一个特殊的方法并按字段复制数据字段。

+0

实际上,* this = * base会给你一个编译器错误,因为没有Child :: operator =(const Base& )定义。你可以做的static_cast (B)= C ;,这将导致基地::运算符=被调用。无论是否有虚拟功能,这总是很好定义的。 – 2012-07-28 21:22:31

+0

我很好奇,为什么你不鼓励这种类型的任务* this = * base?我得到了编译器错误,但我只是铸造了左值作为基本指针,它工作正常。我想我可以创建一个方法来复制所有的数据或重载赋值运算符,但是我的父类有很多数据,而且非常麻烦。 – 2012-07-28 21:23:02

+0

请把'*此= * base'作为概念性的东西,而不是确切的代码。 – 2012-07-28 23:20:38

1

你不能准确地做你想做的事,但你也许可以做类似的事情。如果父类有一个拷贝构造函数,它可以让你创建一个实例是另一个实例的副本,那么您可以使用拷贝构造函数来创建你的父对象,而你的子对象正在建设中:

class Child : public Base 
{ 
    public: 
    Child(const Base &b) : Base(b) { ...} 

现在您有Child对象,其中Base部分与另一个Base对象的对象相同。

0

考虑this是const。当你获得对基类的引用时,你很容易获得对子类某个子集(部分)的引用;基类实例紧密地绑定到类整体(在这种情况下为子类实例)。您可以指导如何初始化该基类(请参阅Ernest的回复),但是您无法打破该链接。

通常一类与基类的内存布局是一样的东西:

[... |基类| ...] ..]

这是字面上嵌入,而不是独立存在(以下是不正常的,我甚至去说,它永远不会发生 - 但这是一个内部编译器选择):

[... |参考-base-class | ...] [] [独立基类实例]

+0

这也是很好的知道!感谢您的发表 – 2012-07-30 23:29:07