83 C++对象模型探索。数据语义学 - 单类,单继承,虚函数的数据成员布局

零, 这里我们先要澄清一个概念,以免在后面的分析中混淆.

之前我们学习的时候知道:类对象的访问是: 类对象的首地址+偏移量。

这个说法在有多继承的情况下是有问题的。可以参考之前 的 关于 this 指针调整的的一些分析。

CSDNicon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/135737616

由于this指针不一定指向类对象的首地址,因此正确的说法是:

类对象成员的访问是通过: this的地址 + 偏移量

一,单个类带虚函数的数据成员布局(复习)

很显然,由于虚函数的存在,单个 类对象 会多一个vptr指针,这个vptr指针是放在整个数据成员布局的开始位置的,占用4字节(以32位windows 为例说明,实际上是占用1个指针的大小)。

那么显而易见。

class Teacher9 {
public:
	int age1;
	char ch1;
	char ch2;
	char ch3;
	
public:
	virtual void func1() {
		cout << "Teacher9 virtual void func1 start" << endl;
	}

	virtual int func2(string str) {
		cout << "Teacher9 virtual int func2 start str = " << str <<  endl;
		return 888;
	}
};

void main() {
	cout<< sizeof(Teacher9) << endl;//12
}

二,子类不带虚函数  继承 父类不带虚函数  数据成员布局(复习)

parent --- son

参考 https://mp.csdn.net/mp_blog/creation/editor/135889041

子类会因为 字节对齐问题 占用空间变大

子类的this对象和父类的this对象都是指向的首地址。

子类内存模型中,会继承父类的私有成员吗? --但是在子类对象中无法访问父类私有变量

三,子类不带虚函数 继承 父类带虚函数

parent  virtual --- son 

class Teacher10parent {
public:
	int parentage;
private:
	int parentprivateage;
public:
	void virtual parentfun1() {
		cout << "Teacher10parent virtual void parentfun1 start" << endl;
	}
};

class Teacher10son :public Teacher10parent {
public:
	int sonage;
};

void main() {
	cout << sizeof(Teacher10parent) << endl;//12,一个vptr指针 + 两个int
	cout << sizeof(Teacher10son) << endl; //16 这说明在子类内存模型中,是会包含父类私有的成员变量的,只是无法访问

}

四,子类带虚函数 继承 父类不带虚函数

parent --- son virtual

//parent   -- - son virtual
class Teacher11parent {
public:
	Teacher11parent() {
		cout << "Teacher11parent 构造函数 this = " << this << endl;
	}
public:
	int parentage;
private:
	int parentprivateage;
public:

};

class Teacher11son :public Teacher11parent {
public:
	Teacher11son() {
		cout << "Teacher11son 构造函数 this = " << this << endl;
	}
	int sonage;

public:
	virtual void teacher11sonfunc() {
		cout << "Teacher11son virtual teacher11sonfunc called" << endl;
	}
};

void main() {
	cout << sizeof(Teacher11parent) << endl;//8
	cout << sizeof(Teacher11son) << endl; //16


	//从结果来看,子类和父类的this指针指向是不同的。
	//这是因为当子类中 有vptr指针的时候,在内存模型中vptr也会放在父类的前面。

	Teacher11son *tson = new Teacher11son;
	tson->parentage = 16;
	tson->sonage = 18;

	long * plong = (long *)tson;
	cout << "tson = " << tson << "   plong = " << plong << "  plong +1  = " << (plong + 1) << endl;
	int age = *(plong + 1);

	cout << "parenet age = " << age << endl;

	Teacher11parent *teap = tson;
	cout << "parenet teap = " << teap << endl;
	//运行结果为:
	//  8
	//	16
	//	Teacher11parent 构造函数 this = 010D5F7C
	//	Teacher11son 构造函数 this = 010D5F78
	//	tson = 010D5F78   plong = 010D5F78  plong + 1 = 010D5F7C
	//	parenet age = 16
	//	parenet teap = 010D5F7C

	printf("Teacher11parent::parentage 偏移量为%p\n", &Teacher11parent::parentage);
	printf("Teacher11son::sonage 偏移量为%p\n", &Teacher11son::sonage);

	//Teacher11parent::parentage 偏移量为00000000
	//	Teacher11son::sonage 偏移量为0000000C
}

五 ,子类带虚函数 继承 父类带虚函数

parent  virtual --- son virtual

parent 的指针和son 的指针指向的是同一个地址。

//parent virtual   -- - son virtual
class Teacher12parent {
public:
	Teacher12parent() {
		cout << "Teacher12parent 构造函数 this = " << this << endl;
	}
public:
	int parentage;
private:
	int parentprivateage;
public:
	virtual void func1(){

	}
};

class Teacher12son :public Teacher12parent {
public:
	Teacher12son() {
		cout << "Teacher12son 构造函数 this = " << this << endl;
	}
	int sonage;

public:
	virtual void teacher12sonvirtualfunc() {
		cout << "Teacher11son virtual teacher11sonfunc called" << endl;
	}
};

void main() {
	cout << sizeof(Teacher12parent) << endl;//12
	cout << sizeof(Teacher12son) << endl; //16
	Teacher12son *tson = new Teacher12son;
	tson->parentage = 9;
	tson->sonage = 8;

	cout << "duandian " << endl;
}



12
16
Teacher12parent 构造函数 this = 011B5F78
Teacher12son 构造函数 this = 011B5F78
duandian

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-29 18:52:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-29 18:52:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-29 18:52:03       82 阅读
  4. Python语言-面向对象

    2024-01-29 18:52:03       91 阅读

热门阅读

  1. 区块链技术的应用场景和优势

    2024-01-29 18:52:03       57 阅读
  2. AT_abc039_b[ABC039B] エージェント高橋君

    2024-01-29 18:52:03       54 阅读
  3. C/C++ malloc、new,free、delete 区别

    2024-01-29 18:52:03       56 阅读