BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #40520同步于 2010/6/17
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

【求助】C++问题

jackbupt
2010/6/17镜像同步8 回复
我定义了一个基类,然后派生一个类。想在基类中定义一个派生类对象,所以定义基类前,先声明了派生类。觉得在基类中定义一个派生类对象是合法的,因为既然是定义基类,只要还没有创建基类对象,就还不用分配内存空间。但是,程序居然报错(程序中已标明报错处)。 说明:如果在基类中定义派生类对象指针那么就没问题。 求大牛指点迷津! 程序如下: #include<iostream> using namespace std; class DerivedItem; class BaseItem { public: BaseItem() { cout<<"Base contructor"<<endl; //di1=(DerivedItem *)this; //di1=this; } private: //DerivedItem *pdi1; DerivedItem di1; //**********报错处******************** }; class DerivedItem:public BaseItem { public: DerivedItem() { cout<<"Derived Constructor"<<endl; } }; int main() { DerivedItem di1; return 0; }
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
shenlei机器人#1 · 2010/6/17
基类中定义一个派生类对象是合法的?
jmpesp机器人#2 · 2010/6/17
【 在 jackbupt 的大作中提到: 】 : 我定义了一个基类,然后派生一个类。想在基类中定义一个派生类对象,所以定义基类前,先声明了派生类。觉得在基类中定义一个派生类对象是合法的,因为既然是定义基类,只要还没有创建基类对象,就还不用分配内存空间。但是,程序居然报错(程序中已标明报错处)。 : 说明:如果在基类中定义派生类对象指针那么就没问题。 : 求大牛指点迷津! : ................... 给你证明下: 反证法 假设lz你这样的写法是对的 那么可以得到如下两个表达式: size_base = size_der + size_const_base (1) size_der = size_base + size_const_der (2) 现在 把 (2) 带入 (1) 推出以下表达式 0 = size_const_base + size_const_der (3) 显然,如果要使得lz的写法成立 必须使得 size_const_base + size_const_der == 0 几乎所有情况 不管是对齐 或者 类内部有成员变量等 都会导致: size_const_base + size_const_der > 0 故 此时矛盾 所以是不可能的 编译器无法实现 因为这个本质上出现数学逻辑上的矛盾 假设存在size_const_base + size_const_der == 0 此时 编译器确实可以实现 也可以计算内存布局大小 但这样写会导致编译器编译过程中将出现回溯 效率严重低下 而且使得编译器编写复杂 最关键的是 将会使得C++类的成员变量访问出现语义错误 或者说 矛盾 所以编译器照样禁止这样的情况出现 对于 size_const_base + size_const_der == 0 的唯一情况是下面: class A; class B { A a; }; class A: public B { }; 或者: class A { B b; }; 此时可得: size_A = size_B (4) 该式有无穷解,也就是说 此时A B的内存大小可以任意设定,并不会出现数学矛盾。 此时 A.b == B.a == A.b.a == B.a.b == ... 这个逻辑很奇怪,。。。 但编译器不允许这么做,具体原因见上面。 故 这样的情况是不许的 但指针情况可不同 因为指针或者引用的大小跟机器字长一样的 32位cpu是4字节 这个是可以计算的 所以这种情况跟上面的完全不同
richlm机器人#3 · 2010/6/17
厉害! 【 在 jmpesp 的大作中提到: 】 : 给你证明下: : 反证法 : 假设lz你这样的写法是对的 : ...................
yc2575757机器人#4 · 2010/6/17
膜拜大牛~~~各种证明~~~服了~~
a206206机器人#5 · 2010/6/17
我记得c++程序设计上说了对任何前向声明的类都不可以创建对象,或者引用其成员,但是可以创建指针
jokerlee机器人#6 · 2010/6/17
【 在 jmpesp 的大作中提到: 】 : 给你证明下: : 反证法 : 假设lz你这样的写法是对的 : ................... ....faint, 一个对象大小的计算问题被你解释成这样
ericyosho机器人#7 · 2010/6/17
包子真学术……
bupteinstein机器人#8 · 2010/6/18
C++规定,在创建一个对象之前,一定要知道对象的大小。 换句话说,当你创建派生类对象时,派生类对象大小是不能经过前向声明知道的,所以编译器拒绝工作。 当然,深层次原因,还是楼上那位高人的数学证明。