C++问题(代码小问题)

来源:百度知道 编辑:UC知道 时间:2024/06/08 19:18:04
class A
{
int x;
int &y;
};
// class B
// {
// int y;
// };
// class C:public A,public B
// {
// int z;
// };

int main()
{
// C c;
// B *p = &c;
// cout<<&c<<endl;
// cout<<p<<endl;
cout<<sizeof(A)<<endl;
return 0;
}
输出为什么是8?

class A
{
int x;
int &y;
};
class B
{
int y;
};
class C:public A,public B
{
int z;
};

int main()
{
C c;
B *p = &c;
cout<<&c<<endl;
cout<<p<<endl;
//cout<<sizeof(A)<<endl;
return 0;
}
输出结果为什么不一样?p不是C的首地址

还请高人指点一二。。。。谢谢啦
今天又重新问了老师一下,第一个例子里面要用显示构造函数用初始化链表初始化。sizeof(double&),应该是指向引用类型的大小为此处为8.(指针类型肯定是4个字节);
那个指针的就不大清楚了,学的还不多,虚函数和继承树还不懂。
谢谢大家了,尤其是yyrryyrr2.
呵呵……

1)class A
{
int x;
int &y;
};
故A的大小是一个int的大小加一个int&的大小(注意:引用类型总是同相同类型的基本类型的指针类型占用一样的大小。例如:sizeof(int&)==sizeof(int*))
为8

2)问题发生在隐式指针转换。
B *p = &c;
对于这一句,&c是(C*)类型,在初始化而p之前会隐式转化成B*类型,由于语言设计,B*类型的指针应该不能访问A基类的数据,所以会跳过A的成员。这里有个例外,在你第二个程序中,如果B中有个虚函数,则在继承树中的任何类指针都将接受虚函数表的地址,而不会有跳跃了。如果A和B中都有虚函数,则又会跳跃,这时实际上会有两个虚函数表。由此可见,多重继承的复杂性。所以现代许多语言都干脆不支持多重继承,例如Java和C#。

注意,指针类型转化一般只是改变指针的性质(运算,解引用时表现出的特性),而不会改变指针的值,这种情况之发生在多重继承时。

另外,正确的编译器都不能编译这段代码。
因为class中的y是个int&,c++规定引用类型必须提供初始化式。换句话说,构造函数必须初始化y,但是编译器为你写的默认构造函数无法初始化这个变量,因为引用不像其他类型内置变量一样,为它赋个0就算对它默认初始化了(默认构造函数实际上什么事都不做,有时候他用CC填充所有未初始化变量),所以无法通过编译。
---------------------------------------------------
补充知识:为助你理解,设想下面的类继承树:
class base{
public:
virtual int func(){return(33);}
long lbase;
};

class A : public base{
public:
A():nrA(0){}
virtual int func(){return (0);}
private:
int nA;
const int &n