类对象作为类成员
class A {};
class B {
A a;
}
静态成员(Static)
静态成员变量
- 所有对象共享同一份数据
- 在编译阶段分配内存(全局区)
- 类内声明,类外初始化
class Person{
public:
static int a; // 类内声明
}
int Person::a = 100; // 类外初始化
两种访问方式:
- 通过对象进行访问
Person p;
p.a;
- 通过类名进行访问
Person::a;
静态成员函数
- 所有对象共享同一函数
- 静态成员函数只能访问静态成员变量
两种访问方式: - 通过对象进行访问
- 通过类名进行访问
C++对象模型
成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象
空对象占用内存空间为1字节,每个空对象应该有一个独一无二的内存地址
Class Person1{
int a;
};
Class Person2{
int a;
static int b;
void func1(){};
static void func2(){};
};
int Person::b = 0;
int main(){
Person p1;
Person p2;
sizeof(p1); // 为4字节
sizeof(p2); // 为4字节,静态成员变量和成员函数不属于对象
return 0;
}
this指针
this指针指向被调用的成员函数所属的对象
用途:
- 当形参和成员变量同名时,可用this指针区分
Class Person {
public:
Person(int age){
this->age = age; // this指针指向被调用的成员函数所属的对象
}
int age;
};
- 在类的非静态成员函数中返回对象本身,可以使用return *this
Class Person {
public:
Person(int age){
this->age = age; // this指针指向被调用的成员函数所属的对象
}
Person& PersonAddAge(Person &p){ // &不能少,否则会生成新的对象,并调用拷贝构造函数
this->age += p.age;
return *this;
}
int age;
};
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); // p2.age变为40,链式编程
空指针访问成员函数
空指针可以访问类的成员函数,但如果函数用到类的属性就会报错,函数需要加以下代码进行判断。
if(this == nullptr)
return;
const 修饰成员函数
常函数:函数 + const
- 常函数不可以修改成员属性
- 成员属性声明时加关键字mutable后,在常函数中可以修改
class Person {
public:
void func() const {
a = 10; // 报错
}
int a;
};
class Person {
public:
void func() const {
a = 10; // 正确
}
mutable int a;
};
常对象:const + 对象
- 常对象只能调用常函数,不能修改成员属性
- 成员属性声明时加关键字mutable后,在常对象中可以修改
class Person {
public:
void func1() const {
a = 10;
}
void func2() {
...
}
mutable int a;
};
const Person p;
p.func1(); // 正确
p.func2(); // 错误