C++对象模型和this指针详解

目录
  • 对象模型
    • 一、
    • 二、
    • 三、
    • 四、
    • 五、
  • this指针
    • 一、
    • 二、
  • 总结

对象模型

成员变量和成员函数分开存储

一、

只有非静态成员变量才属于类的对象上

空对象占用字节为1

 class Person
{
};
void test01()
{
	Person p;
	cout << "size of = " << sizeof(p) << endl;
}
int main()
{
	test01();
	system("pause");
	return 0;
}

占用内存空间为 1 的原因是:如果有其他的空对象,各自分配一个内存空间可以让两者之间相互区别,而且 1 字节也很省内存。 所以每个空对象都会有一个自己的内存地址。

二、

class Person
{
	int m_A;//改为有内容
};
void test02()
{
	Person p;
	cout << "size of = " << sizeof(p) << endl;
}
int main()
{
	test02();
	system("pause");
	return 0;
}

因为 int 类型 ,不把之前的空类型考虑进去。

三、

将Person类改为

class Person
{
	int m_A;// 非静态成员变量 属于类的对象上
	static int m_B;// 添加 静态成员变量 不属于类的对象上
};
int Person::m_B = 0;

非静态成员变量 属于类的对象上

静态成员变量,不属于类对象上

所以不考虑在内

四、

class Person
{
	int m_A;// 非静态成员变量 属于类的对象上
	static int m_B;// 添加 静态成员变量 不属于类的对象上
	void func()  //非静态成员函数
	{
	}
};
int Person::m_B = 0;

所以成员变量和成员函数是分开存储的,非静态成员函数不属于类对象上

五、

static voidfunc()

{}

静态成员函数也不会增加 不属于类对象上

this指针

用于区分类中多个对象调用函数时,分别都是哪个函数在调用自己。

this 指针指向被调用成员函数所属的对象

特点:

1. this指针是隐含每一个非静态成员函数内的一种指针

2.this 指针不需要定义,直接使用即可。

用途:

1.当形参和成员变量同名时,可用this指针来区分

2.在类的非静态成员变量中返回对象本身,可使用return *this

一、

  class Person
{
public:
	Person(int age)//变量
	{
		//this指针指向的是被调用成员函数的所属对象
		//即 p1, 所以可以解决和变量的名称冲突
		this->age = age;//前一个为成员变量,后一个age为形参
	}
	int age;
};
void test01()
{
	Person p1(18);
	cout << "p1的年龄为: " << p1.age << endl;
}
main()
{
	test01();
	system("pause");
	return 0;
}

如果不加 this 都会默认为形参 age ,从而报错。

this 指向被调用的对象,此时为 p1。

二、

class Person
{
public:
	Person(int age)
	{
		//this指针指向的是被调用成员函数的所属对象
		//即 p1, 所以可以解决和变量的名称冲突
		this->age = age;
	}
	void PersonAddAge(Person &p)
	{
		this->age += p.age;
	}
	int age;
};
void test01()
{
	Person p1(18);
	cout << "p1的年龄为: " << p1.age << endl;
}
//返回对象本身用*this
void test02()
{
	Person p1(10);
	Person p2(10);
	p2.PersonAddAge(p1);
	cout << "p2年龄:" << p2.age << endl;
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

此时p2为 20 ,若要多次相加需要改动为

class Person
{
public:
	Person(int age)
	{
		//this指针指向的是被调用成员函数的所属对象
		//即 p1, 所以可以解决和变量的名称冲突
		this->age = age;
	}
	Person& PersonAddAge(Person &p)//此处void 改为Peroson是因为返回值如果是p2的话,就可以将p2.PersonAddAge(p1) 看作p2,然后继续调用之后的PersonAddAge(p1)
	//此处的Person &p是以 引用的方式传入
	//此处的Person& 是以引用的方式返回
	{
		this->age += p.age;
		// this是指向p2的指针,而*this就是p2本体
		return* this;
	}
	int age;
};
void test01()
{
	Person p1(18);
	cout << "p1的年龄为: " << p1.age << endl;
}
//返回对象本身用*this
void test02()
{
	Person p1(10);
	Person p2(10);
	p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
	cout << "p2年龄:" << p2.age << endl;
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

链式编程思想:可以往后无限的追加。

但如果函数,不使用引用方法,返回的是一个值,就会创建新的对象

Person PersonAddAge(Person &p)//不使用引用方法
	{
		this->age += p.age;
		// this是指向p2的指针,而*this就是p2本体
		return* this;
	}
	int age;
};

在第一次调用Person PersonAddAge()后 ,p2加了10, 但在这之后返回的并不是本体了,而是根据本体创建的一个新的数据。Person 和 *this 是不一样的数据(见拷贝构造函数的调用时机-以值方式返回局部对象)。 所以每一次Person PersonAddAge()后,都是一个新的对象,所以最后输出结果p2 是不变的20。

疑问:至于为什么不是p2 为 10 。 以值方式返回局部对象会调用拷贝构造函数。对p2进行一次PersonAddAge操作后,将p2的结果拷贝为p2' 。所以p2还是经过了一次加年龄的操作的 。对p2进行一次PersonAddAge操作后,将p2的结果拷贝为p2'

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 深入理解C++的对象模型

    何为C++对象模型? C++对象模型可以概括为以下2部分: 1. 语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 引言 现在有一个Point类,声明如下: class Point { public: Point(float xval); virtual ~Point(); float x() const; static int PointCount(); protected: virtual ostream& print(ostream &os) const; fl

  • C++ 中this指针的用途详解

    目录 1.区分形参和变量同名时: 2.return *this返回函数本身 总结 先说结论: 1.形参和变量同名时,可用this指针来区分 2.在类的非静态成员函数中返回本身,可用return *this 1.区分形参和变量同名时: #include <iostream> using namespace std; class Person { public: Person(int age) { age = age; } int age; }; void test01() { Person p1

  • 带你了解C++this指针的用法及其深究

    目录 前言 一.this指针是个什么东东,重要吗? 二.案例理解 主要的用途 总结 前言 今天,码神像一个新车手一样,尝试着用模板来更新一下,不要建议哦,毕竟没有放弃爱情的拓海也不是真正的车神,哈哈,发车了 一.this指针是个什么东东,重要吗? 首先,我以码神的名义起誓,this指针绝对重要,尤其是对于c++这个面向对象编程的语言来说! 有的码手可能要说了:你说重要就重要?那我还说不重要呢? 这个么,空口无凭,我现在来举一个例子: 我们知道对于一个类来说,要有很多工作要做,其中类的成员函数可以

  • C++ 多重继承和虚拟继承对象模型、效率分析

    一.多态 C++多态通过继承和动态绑定实现.继承是一种代码或者功能的传承共享,从语言的角度它是外在的.形式上的,极易理解.而动态绑定则是从语言的底层实现保证了多态的发生--在运行期根据基类指针或者引用指向的真实对象类型确定调用的虚函数功能!通过带有虚函数的单一继承我们可以清楚的理解继承的概念.对象模型的分布机制以及动态绑定的发生,即可以完全彻底地理解多态的思想.为了支持多态,语言实现必须在时间和空间上付出额外的代价(毕竟没有免费的晚餐,更何况编译器是毫无感情): 1.类实现时增加了virtual

  • C++ 中的this指针详解及实例

    C++ this 指针详解 学习 C++ 的指针既简单又有趣.通过指针,可以简化一些 C++ 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的.所以,想要成为一名优秀的 C++ 程序员,学习指针是很有必要的. 正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址. this指针是类的一个自动生成.自动隐蔽的私有成员,它存在于类的非静态成员中,指向被调用函数所在的对象. 全局仅有一个this指针,当一个对

  • C++对象模型和this指针详解

    目录 对象模型 一. 二. 三. 四. 五. this指针 一. 二. 总结 对象模型 成员变量和成员函数分开存储 一. 只有非静态成员变量才属于类的对象上 空对象占用字节为1 class Person { }; void test01() { Person p; cout << "size of = " << sizeof(p) << endl; } int main() { test01(); system("pause");

  • C语言指针详解

    前言:复杂类型说明     要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: int p; //这是一个普通的整型变量   int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所

  • Python对象类型及其运算方法(详解)

    基本要点: 程序中储存的所有数据都是对象(可变对象:值可以修改 不可变对象:值不可修改) 每个对象都有一个身份.一个类型.一个值 例: >>> a1 = 'abc' >>> type(a1) str 创建一个字符串对象,其身份是指向它在内存中所处的指针(在内存中的位置) a1就是引用这个具体位置的名称 使用type()函数查看其类型 其值就是'abc' 自定义类型使用class 对象的类型用于描述对象的内部表示及其支持的方法和操作 创建特定类型的对象,也将该对象称为该类

  • C++中函数指针详解及代码分享

    函数指针 函数存放在内存的代码区域内,它们同样有地址.如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,如同数组的名字就是数组的起始地址. 1.函数指针的定义方式:data_types (*func_pointer)( data_types arg1, data_types arg2, ...,data_types argn); c语言函数指针的定义形式:返回类型 (*函数指针名称)(参数类型,参数类型,参数类型,-); c++函数指针的定义形式:返回类型 (类名

  • C/C++静态类和this指针详解及实例代码

     C/C++静态类和this指针详解 1.静态类 C++的静态成员不仅可以通过对象来访问,还可以直接通过类名来访问. class CBook{ public: static double price;//需要通过类外来进行初始化 } int main(void){ CBook book; book.price;//通过对象来访问 CBook::price//通过类名来访问 return 0; } 静态成员变量 对应静态成员有以下几点需要注意: (1)静态数据成员可以是当前类的类型,而其他数据成员

  • TypeScript数组实现栈与对象实现栈的区别详解

    目录 前言 数组实现栈 实现思路 实现代码 编写测试代码 对象实现栈 实现代码 编写测试代码 二者的区别 十进制转二进制 前言 栈作为一种数据结构,它可以应用在很多地方,当你需要经常获取刚存放进去的数据时,那么栈这种数据结构将是你的首选. 栈的实现方式一般有两种:数组实现和对象实现,这两种实现方式最终实现的功能都是一样的,但是在性能上却有着很大的差别. 本文将详细讲解这两种实现方式的差异并用TypeScript将其实现,欢迎各位感兴趣的开发者阅读本文. 数组实现栈 本文讲解的是栈用代码的实现,如

  • C++ boost scoped_ptr智能指针详解

    目录 一.智能指针-唯一所有者 二.接口类分析 一.智能指针-唯一所有者 boost::scoped_ptr 是一个智能指针,它是动态分配对象的唯一所有者. boost::scoped_ptr 无法复制或移动.此智能指针在头文件 boost/scoped_ptr.hpp 中定义. 二.接口类分析 scoped_array 分析 scoped_array 的类部分原始代码如下: template<class T> class scoped_array // noncopyable { priva

  • C++ Boost PointerContainer智能指针详解

    目录 一.提要 二.智能指针Boost.PointerContainer 三.练习 一.提要 在 C++11 中,Boost.PointerContainer是另一个智能指针,一般是用来生成集合数据的,本文阐述这种指针的特点和用法. 二.智能指针Boost.PointerContainer 库 Boost.PointerContainer 提供专门用于管理动态分配对象的容器.例如,在 C++11 中,您可以使用 std::vector<std::unique_ptr<int>> 创

  • C语言指针详解及用法示例

    新手在C语言的学习过程中遇到的最头疼的知识点应该就是指针了,指针在C语言中有非常大的用处.下面我就带着问题来写下我对于指针的一些理解. 指针是什么? 指针本身是一个变量,它存储的是数据在内存中的地址而不是数据本身的值.它的定义如下: int a=10,*p; p=&a int a=10; int *p=&a; 首先我们可以理解 int* 这个是要定义一个指针p,然后因为这个指针存储的是地址所以要对a取地址(&)将值赋给指针p,也就是说这个指针p指向a. 很多新手都会对这两种定义方法

随机推荐