好久没有写日记了,呵呵最近挺忙论文工作,愁死了。
今天小师妹问了我一个问题,关于sizeof,居然没有解答出来,悲哀,呵呵。进行了一顿狂补。结果如下
1。 问题
class A
{
int a;
public:
op(){a=14;};
int read(){return a ;}
int as (){return a*a;}
};
与 class B
{
int a;
public:
op(){a=14;};
};
大小一样
编译器究竟把成员函数放在哪里?成员函数又怎么样和类关联起来?
解答如下:
我们先来看看类的内存结构吧: (转自CSDN Muf(沐枫))
class A
{
int a;
public:
op(int value){a=value;};
int read(){return a ;}
public
virtual int as(){return a*a;}
};
对于以上的类的说明,当创建一个实例时,其内存结构如下(不同的C++实现略有不同):
+0000: 成员变量 int a
+0004: $A$vtable指针 --> +0000: 成员函数指针 as
为什么op函数和read函数不需要在类中体现呢?因为没有必要。
当C++编译以上的类时,它会产生类似以下的成员函数(不同的C++实现略有不同):
//op函数
int $A$op@i_(A* this, int value) {this->a = value;}
//read函数
int $A$read@_(A* this) {return this->a;}
//as函数
int $A$as@_(A* this) {return this->a * this->a;}
也就是说,函数名本身就指明了函数是属于哪个类的(连参数类型都有),因此,编译器在编译代码时,可以直接调用该类的成员函数,而不需要类本身提供任何信息。
例(0):
A a;
对于函数调用:
a.read();
此时,a是A的实例,因此编译生成代码为:
$A$read@_(&a);
例(1):
A a;
对于函数调用:
a.as();
此时,a是A的实例,因此编译生成代码为:
$A$as@_(&a);
例(2)
A* pa;
对于函数调用:
pa->read();
对应生成代码为:
$A$read@_(pa);
例(3)
A* pa;
对于函数调用:
pa->as();
对应生成代码为:
(pa->$A$vtable[0])(pa);
请注意:
如果不是用指针调用,那么是不是virtual函数,调用方法是一样的,参见例(0)和例(1)
如果是指针调用,例(2)和例(3)就是调用virtual函数和普通成员函数的区别。就因为有这区别,所以virtual函数必须在类中占一席之地
2。关于sizeof大小的问题 (可参考http://zhang4331.blog.com.cn/archives/2007/2509985.shtml)
class A {
public:
virtual void fun0() { cout << "A::fun0" << endl; }
int a;
int b;
};
int main(int argc, char* argv[])
{
A a;
cout << "Size of A = " << sizeof(a) << endl;
return 0;
}
结果是12。
class A {
public:
virtual void fun0() { cout << "A::fun0" << endl; }
int a;
int b;
double c;
};
int main(int argc, char* argv[])
{
A a;
cout << "Size of A = " << sizeof(a) << endl;
return 0;
}
结果为24。double+Two int+Virtual(原为四)=8+8+8=24
即sizeof的值为粒度最大的值的整数倍。
3。单继承与多继承
#include "iostream.h"
#include "string.h"
#include "stdlib.h"
class A {
public:
virtual void f() { cout << "A::f" << endl; }
};
class B :public A{
public:
virtual void f() { cout << "B::f" << endl;}
};
class C :public A {
public:
virtual void f() { cout << "C::f" << endl;}
};
class Drive : public C {
public:
virtual void f() { cout << "D::f" << endl;}
};
int main(int argc, char* argv[])
{
A a;
B b;
C c;
Drive d;
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
cout << sizeof(c) << endl;
cout << sizeof(d) << endl;
system("pause");
return 0;
}
结果全为4。
class A {public: virtual void f() { }};
class B {public: virtual void f() { }};
class C {public: virtual void f() { }};
class Drive : public A, public B, public C {};
int main()
{ Drive d;
cout << "Size is = " << sizeof(d) << endl;
return 0;}
结果如下:Size is = 12 ,相信大家一看下面的结构图就会很清楚,
4。但是在class A{}中sizeof(A)却为1,不知道为什么?
自己补充一下:
另一个要注意的是,当类中没有任何成员变量,也没有虚函数的时候,该类的大小是多少呢?
例如:
class B2
{
void fun(void);
}
此时sizeof(B2)的值是多少呢?在C++早期的编译器中,这个值为0;然而当创建这样的对象时,
它们与紧接着它们后面的对象有相同的地址。比如:
B2 b2;
int a;
那么对象b2与变量a有相同的地址,这样的话对对象b2地址的操作就会影响变量a。所以在现在大多数编译器中,该值的大小为1。