C++核心(面向对象)
类和对象
对象模型和this指针
1.成员变量和成员函数分开存储
- C++中,类内成员变量和成员函数分开存储
- 只有非静态成员变量才属于类的对象上
- 其余的静态成员变量、静态成员函数和非静态成员函数都不属于类的对象上
#include <iostream>
#include <string>
using namespace std;
class Person
{
};
class Person1
{
public:
int m_a;
};
class Person2
{
public:
static int m_a;
void func()
{
}
static void func2()
{
}
};
int main()
{
Person p;
cout<<"空对象的大小:"<<sizeof(p)<<endl; //1
Person1 p1;
cout<<"含有非静态成员变量的对象大小:"<<sizeof(p1)<<endl; //4
Person2 p2;
cout<<"含有静态成员变量的对象大小:"<<sizeof(p2)<<endl; //1
cout<<"含有非静态成员变函数的对象大小:"<<sizeof(p2)<<endl; //1
cout<<"含有静态成员函数的对象大小:"<<sizeof(p2)<<endl; //1
return 0;
}
注:空对象占用的内存空间是1字节大小。
2.this指针概念
- 每一个非静态成员函数只会产生一份函数实例,也就是说多个同类型的对象会共用一块代码,这块代码是如何区分哪个对象调用自己呢
- C++通过提供特殊的对象指针来解决上述问题
- this指针指向被调用成员函数的所属对象
- this指针是隐含每一个非静态成员函数内的一种指针
- this指针不需要定义,直接使用即可
this指针的用途:
- 当形参和成员变量同名时,可用this指针区分
- 当类的非静态成员函数中返回对象本身,可使用return *this
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
Person(int age)
{
this->age = age; //形参与成员变量同名
}
void PaddP(Person p)
{
this->age += p.age;
}
Person & PaddP1(Person p) //本体返回值为引用类型
{
this->age += p.age;
return *this; //this指向对象的指针,则*this是对象的本体
}
Person PaddP2(Person p) //返回值为值,需要调用拷贝构造函数,创建一个新的对象
{
this->age += p.age;
return *this; //this指向对象的指针,则*this是对象的本体
}
int age;
};
void test01()
{
Person p1(18);
cout<<p1.age<<endl;
}
void test02()
{
Person p2(20);
Person p3(20);
//p3.PaddP(p2);
//cout<<"p3的第一次年龄:"<<p3.age<<endl; //40
//p3.PaddP1(p2).PaddP1(p2).PaddP1(p2); //链式编程
//cout<<"p3的第二次年龄:"<<p3.age<<endl; //80
p3.PaddP2(p2).PaddP2(p2).PaddP2(p2); //链式编程
cout<<"p3的第三次年龄:"<<p3.age<<endl; //第一次加为一个对象p3_1=40,第二次加为一个新对象p3_2=40,第三次加为另一新的对象p3_3=40
}
int main()
{
//test01();
test02();
return 0;
}
3.空指针访问成员函数
- C++中空指针也可以调用成员函数,但是要注意有没有用到this指针,如果用到this指针,需要加以判断保证代码的健壮性
#include <iostream>
using namespace std;
class Person{
public:
void showPersonName()
{
cout<<"this is Person Name!"<<endl;
}
void showPersonAge()
{
if(this == NULL)
{
return;
}
cout<<"age="<<m_Age<<endl; //成员函数中默认隐藏一个this指针,即this->m_Age,此时需要判断this指针
}
int m_Age;
};
void test01()
{
Person * p = NULL; //只定义了一个空指针,没有对象
p->showPersonName();
p->showPersonAge(); //内含this指针,空指针无法访问属性,需提高代码健壮性
}
int main()
{
test01();
return 0;
}
4.const修饰成员函数
常函数
- 成员函数后加const我们称这个函数为常函数
- 常函数内不可以修改成员属性
- 成员属性声明时加关键字mutable后,在常函数中仍然可以进行修改
常对象
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数
#include <iostream>
using namespace std;
class Person {
public:
void showPerson() const //常函数
{
//this->m_A = 100;
this->m_B = 100;
}
void func()
{
cout<<"可以吗?"<<endl;
}
//int m_A;
mutable int m_B; //mutable类型的特殊变量,在常函数中可以修改此值
};
void test01()
{
Person p;
p.showPerson();
}
void test02()
{
const Person p; //常对象
//p.m_A = 100; //常对象不可以修改成员变量
p.m_B = 100; //特殊变量,常对象可以修改
p.showPerson(); //常对象只可以调用常函数
//p.func(); //常对象不可以调用普通成员函数
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
总结:this指针的本质是指针常量,即指针的指向不可以修改,Person * const this;成员函数后加const,修饰的是this指针的指向,即指针指向的值也不可以修改,const Person * const this。