在C++中,类的成员变量和成员函数分开存储
类的成员变量
只有非静态成员变量才属于类的对象!!(静态成员变量、函数都不属于类的对象)
看下述代码段,在其中,说明了只有非静态成员变量才属于类的对象;静态成员函数、静态成员变量、以及成员函数都不属于类的对象
且在空的类当中,其所占内存空间为1个字节,目的是为了在内存空间中使得类的空间得到定位;
而一旦在类中,出现了非静态的成员变量,(假设为整形)那么此时类的大小为4字节。
class Person
{
int m_A;//非静态成员变量
static int m_B;
void func()//非静态成员函数,也不属于任何对象
{
}
static void func2()
{
}
};
int Person::m_B = 10;
void test01()
{
Person p;
//为什么空类的内存空间大小为1?
//因为C++编译器会给每个空对象也分配一个字节空间,为了区分空对象占内存空间的位置
//每个空对象也应该有一个独一无二的内存地址
cout << "size of p = " << " " << sizeof(p) << endl;//空类的内存空间为:1
//然后有整数型的成员变量后,打印结果为4;因为一旦有了成员变量后,就可以把区分的位置字节删除
//在加上静态成员变量后,打印的结果仍然是4,所以静态成员变量不属于任何对象。
//成员函数与成员变量是分开存储的,且非静态成员函数也是不属于任何类的
//静态成员函数也是不属于任何类的
}
int main()
{
test01();
system("pause");
}
this指针
this指针的概念
首先提出问题,C++中,成员变量和成员函数是分开存储的
每一个非静态成员函数只会诞生一份函数实例,也就是说,多个同类型对象会共用一块代码
那么 这一块代码 如何区分哪个对象调用自己呢?
C++提供特殊的对象指针,this指针,解决上述问题
this指针指向被调用的成员函数所属的对象
this指针是隐含每一个非静态成员函数的一种指针!
this指针不需要定义,直接使用即可!
this指针的用途:
1. 当形参和成员变量同名时,可用this指针区分
2. 在类的非静态成员函数中返回对象本身,可使用return *this
然后用下述代码段来做一个案例:
首先从有参构造函数来说,成员变量的名称与构造函数形参的名称重复了;结合this指针特性:
this指针是隐含每一个非静态成员函数的一种指针!
this指针不需要定义,直接使用即可!
所以可以用this指针解决,方法如下代码:
class Person
{
public:
Person(int age)//这些age是重复的,并没有将成员变量进行赋值
{
this->age = age;//this指针指向的是被调用的成员函数所属的对象
}
//如果是用Person来接收返回值,那么每次都会创建新的对象,依次进行拷贝并创建新的对象
//引用实质上是指针,所以一直指向,值得以叠加,但是Person本身会反复创建对象,所以不可以叠加。
Person& PersonAddAge(Person &p) {
this->age += p.age; //(被调用函数的)自身的年龄+=传入对象年龄
return *this;//返回的是被调用成员函数所属的对象(p2)
}
//如果返回对象本体,需要用引用的方式作一个返回!
//如果是用Person来进行返回类型定义,就相当于重新创建了一次函数,无法起到叠加的效果(每次都会重新创建)
int age;
};
//1. this解决名称冲突
void test01()
{
Person p1(18);//this指针指向的是被调用的成员函数所属的对象,即p1
cout << "p1年龄: " << p1.age;
}
//2. 返回对象本身,用*this
void test02()
{
Person p2(10);
Person p3(10);
//链式编程思想
p2.PersonAddAge(p3).PersonAddAge(p3).PersonAddAge(p3);//在p2内调用,将p3传递过去
//想要多次叠加年龄,需要从函数入手;如果返回值为p2,那么就可以多次调用
cout << "p2的年龄为 : " << p2.age << endl;
}
int main()
{
test01();
cout << endl;
test02();
system("pause");
}
然后,对于代码段中的链式编程思想:
由于我们在实际工程中,创建很多对象的情况下,有时需要对对象中的某些特定的成员变量叠加,如果按照常规写法,会有些麻烦;于是先创建一个空的(或者是现有的)对象,然后在类中书写
Person& PersonAddAge(Person &p)这样形式的函数;其好处在于:使用引用,避免空间浪费;同时由于返回类型为对象引用(指针);所以可以多次对对象中的成员函数进行调用(返回整体还是对象,整体再调用成员函数,再返回再调用。。。。)
所以就引出了链式编程方法;
通过上述的解释,也就可以理解:p2.PersonAddAge(p3).PersonAddAge(p3).PersonAddAge(p3);即在p2内调用,将p3传递过去,然后整体返回作为对象,然后对象再次调用成员函数;以此实现多次访问的目的;