1.成员变量和成员函数分开存储
#include <iostream> using namespace std; // 空类的对象 size 为1 class NullClass{ }; class Person{ int m_A; // 非静态成员变量 属于类的对象上 }; class All{ int m_A; // 非静态成员变量 属于类的对象上 static int m_B; // 静态成员变量 不属于类的对象上 void func(){} // 非静态成员函数 不属于类的对象上 static void func2(){} // 静态成员函数 不属于类的对象上 }; int All::m_B = 0; void test01(){ NullClass p; cout << "size of 空类对象 p = "<< sizeof(p) << endl; Person q; cout << "size of 包含非静态成员变量的对象 q = "<< sizeof(q) << endl; All a; cout << "size of 包含所有的对象 a = "<< sizeof(a) << endl; } int main(){ test01(); }
2.this指针概念
#include <iostream> using namespace std; // this指针 // 用来指向被调用的成员函数所属的对象 // 用途1: 解决形参和属性名冲突 // 用途2: 在类的非静态成员函数中返回对象本身,可使用return *this class Person{ public: Person(int age){ // age = age; // 形参和属性名冲突 this->age = age; // 1,使用this指针解决冲突 } // 返回类型时Person时, 是以值的方式返回,会调用拷贝构造函数,返回一个新的p2 Person FalsePersonAddAge(Person p){ this->age += p.age; return *this; } // 返回类型时Person&时, 是以引用的方式返回,返回的是p2本身 Person& TruePersonAddAge(Person p){ this->age += p.age; return *this; // 2.在类的非静态成员函数中返回对象本身,可使用return *this } int age; }; void test01(){ Person p1(10); cout << "p1 age = " << p1.age << endl; Person p2(10); p2.FalsePersonAddAge(p1).FalsePersonAddAge(p1).FalsePersonAddAge(p1); // 链式编程思想 cout << "p2 age = " << p2.age << endl; // 20 Person p3(10); p3.FalsePersonAddAge(p1).FalsePersonAddAge(p1).FalsePersonAddAge(p1); // 链式编程思想 cout << "p3 age = " << p3.age << endl; // 40 } int main(){ test01(); }
3.空指针访问成员函数
#include <iostream> using namespace std; // C++中 空指针也可以调用成员函数,但要注意成员函数中有没有用到this指针 // 如果用到了,需要在成员函数中加以判断,保证代码的鲁棒性 class Person{ public: void showClassName(){ cout << "Person 类" << endl; } void showPersonAge(){ // 报错原因是因为传入指针为NULL,因此要加上判断, 这样就不会报错了 if(this != NULL){ cout << "age = " << m_age << endl; // 编译器默认会加上 this->m_age } } int m_age; }; void test01(){ // 空指针, 类型为Person * Person * p = NULL; p->showClassName(); p->showPersonAge(); } int main(){ test01(); }
4.const修饰成员函数
#include <iostream> using namespace std; // 常(成员)函数 // 1.成员函数后加const 表示这个函数为常成员函数 // 2.常成员函数内不可以修改成员属性 // 3.但是如果成员属性声名时加上mutable关键字,在常成员函数中依然可以修改 // 常对象 // 1. 声名对象时加const修饰 表示这个对象为常对象 // 2. 常对象只能调用常成员函数 class Person{ public: void showPerson() const // 常成员函数 { // m_A = 100; // 报错,不允许修改 相当于this—>m_A = 100 // this指针本质是指针常量,指向不可以修改,但指向的值可以修改,相当于Person * const this // 成员函数加上const,修饰的是this指针的指向,相当于 const Person * const this } int m_A; }; class Person2{ public: void showPerson2() const // 常成员函数 { m_A = 100; // 不报错,允许修改 cout << "m_A = " << this->m_A << endl; } void func(){ } mutable int m_A; // 加上mutable关键字 }; void test01(){ const Person2 p; // 常对象 p.m_A = 0; p.showPerson2(); // p.func(); // 报错,常对象不能调用除常函数外的函数 // 因为func()可以对属性进行修改,如果常对象能调用除常函数外的函数,那么就会间接修改属性,这样是不行的 } int main(){ test01(); }