一个类中都有什么元素呢?
成员变量、成员函数。
成员变量又分普通的成员变量、static静态成员变量、const常量
成员函数分为普通成员函数、静态成员函数、虚函数、纯虚函数等
那么他们分别又是如何在类的内存中分配的呢?
1.内存对齐原则
不论是在类中还是在结构体中,都需要内存对齐,具体对齐方式(有一个对齐系数——可以自己定义,同常是2、4或4的倍数,不是对齐系数倍数的元素会扩展到对齐系数的倍数上,整体的内存大小也是对齐系数的整数倍)。
2.空类
作为空类在内存中编译器会自动为该类申请一字节的内存空间,方便在代码区存储这个类。
3.成员变量在内存中的存储方式
顺序存贮!在内存中,不论类中的普通变量(即存在栈中的变量)是私有类型还是共有类型、保护类型,在内存中的存贮方式都是顺序存储结构,const(常量)类型在内存中依旧是顺序结构。但是静态变量由于要在主函数外部、类外部进行变量的再次空间赋值声明,导致并没有存在类里的同一块栈空间里,而是另一块的栈空间,所以他们之间的内存空间是不连续的。
4.成员函数在内存中的存储方式
作为一个类的成员函数,这些成员函数在编译的时候就已经放到了代码区,在运行时再分配内存。同一个类的所有对象共享同一段代码区内存的成员函数,相当于对象只实例化其中变量的地址,并没有实例化函数,函数是一直存在哪里的。不论是普通成员函数还是静态了、常量啦、虚函数啦、纯虚函数就不一样了!在内存中都是链式结构存储的。(也有可能有什么规律但是在我输出内存看的时候并没有发现)
#include <iostream>
#include <cstdio>
using namespace std;
// 可以看到空类编译时也会分配一个字节内存,隐含添加内存
class A {
};
// 类中的成员变量内存分布像结构体一样,有内存对齐,并且是连续分配内存空间的
class B {
public:
int a;
int b;
char c;
};
// 不过其中的char类型成员变量我就没有看懂了
class C {
public:
char a; // char 类型成员变量非常的奇怪
};
class D {
public:
int a;
int b;
void func1 () {}
void func2 () {
int i;
}
virtual void func3 () {
cout << "virtual" << endl;
}
};
class ownerShip {
private:
int a;
int b;
public:
int c;
ownerShip () {
}
void coutAddress () {
cout << "ownerShip a address is : " << &a << endl;
cout << "ownerShip b address is : " << &b << endl;
cout << "ownerShip c address is : " << &c << endl;
// 要注意此处有两种写法,一是通过全局的类名字方式访问成员函数,另一种是通过this指针传递过来的类内部
printf ("ownerShip coutAddress is : %p \n", (void *)&ownerShip::coutAddress);
printf ("ownerShip coutAddress is : %p \n", (void *)&this->coutAddress);
printf ("ownerShip func address is : %p \n", (void * ) &this->func);
printf ("ownerShip func1 address is : %p \n", (void *) &this->func1); // 虚函数
//printf ("ownerShip func2 address is : %p \n", (void *) &this->func2); // 纯虚函数
printf ("ownerShip func3 address is : %p \n", (void *) &this->func3); // 静态函数
}
// 成员函数有一个指向自己类的指针,意味着成员函数可以通过调用this指针调用这个函数自身
void func () {
}
virtual void func1 () {
cout << 1 << endl;
}
//virtual void func2 () = 0;
static void func3 () {
cout << 2 << endl;
}
const void func4 () {
cout << 3 << endl;
}
const static func5 () {
cout << "fuck" << endl;
}
static const func6 () {
cout << "fuck!!" << endl;
}
};
/*
class sub_for_virtual : public ownerShip{
public:
void func2 () {
cout << "sub virtual" << endl;
}
};
/**/
class verifyVar {
private:
int a;
double b;
static int e;
static int g;
const int j = 1;
public:
float c;
bool d;
static int f;
static int h;
const int i = 2;
void func () {
// 顺序结构
cout << "verify a address is : " << &a << endl;
cout << "verify b address is : " << &b << endl;
cout << "verify j address is : " << &j << endl;
cout << "verify c address is : " << &c << endl;
//cout << &e << endl;
//cout << &f << endl;
cout << "verify d address is : " << &d << endl;
cout << "verify i address is : " << &i << endl;
printf ("%p\n", (void*)&this->func);
}
};
class funcStorage {
public:
int func () {}
virtual void func1 () {}
static func2 () {}
const func3 () {}
void cout_ () {
cout << endl;
printf ("func is : %p\n", (void*)&this->func);
printf ("func1 is : %p\n", (void*)&this->func1);
printf ("func2 is : %p\n", (void*)&this->func2);
printf ("func3 is : %p\n", (void*)&this->func3);
}
};
int e = 0;
int f = 1;
int g = 2;
int h = 3;
int main ()
{
A a;
cout << sizeof (A) << endl;
cout << sizeof (a) << endl;
B b;
cout << sizeof (B) << endl;
cout << sizeof (b) << endl;
cout << "B address : " << &b << endl;
cout << "B->a address : " << &(b.a) << endl;
cout << "B->b address : " << &(b.b) << endl;
cout << "B->c address : " << &(b.c) << endl;
C c;
cout << "C address : " << &c << endl;
cout << "C->a address : " << &(c.a) << endl;
D d;
cout << "D size is : " << sizeof (D) << endl;
cout << "D address is : " << &d << endl;
cout << "D->b address is : " << &d.b << endl;
//cout << "D->func1 address is : " << (int*)&D::func1 << endl;
printf ("D->func1 address is : %p \n", (void *)&d.func1);
printf ("D->func2 address is : %p \n", (void *)&d.func2);
printf ("D->func3 address is : %p \n", (void *)&d.func3);
D _d;
cout << "_D->b address is : " << &_d.b << endl; // 可以见得不同对象之间的成员变量存储在不同的内存空间,但是同一个类的成员函数却不一样,都存在同一段代码段中。
//sub_for_virtual sub;
ownerShip *ownership = new ownerShip ();
ownership->coutAddress();
verifyVar verifyvar;
verifyvar.func ();
// 很奇怪的存储方式,不是顺序结构,可能是链式结构
cout << &e << endl;
cout << &g << endl;
cout << &f << endl;
cout << &h << endl;
//cout << "????";
funcStorage funcstorage ;
funcstorage.cout_();
cout << endl;
return 0;
}