
类可以作为另一个类的成员
代码:
- #include
- using namespace std;
- class phone {
- public:
- string shouji;
- phone(string shouji1) :shouji(shouji1) {
- cout << "phone的构造函数调用" << endl;
- }
- ~phone() {
- cout << "phone的析构函数调用" << endl;
- }
- };
- class person {
- public:
- int age;
- string name;
- phone shouji;
- //隐式转换相当于shouji=phone(shouji1)
- person(int a, string name1, string shouji1) :age(a), name(name1), shouji(shouji1) {
- cout << "person的构造函数调用" << endl;
- }
- ~person() {
- cout << "person的析构函数调用" << endl;
- }
- };
- void fun() {
- person p(23, "小明", "苹果");
- }
- int main() {
- fun();
- return 0;
- }

注意:
创建类时,被包含的类的构造函数先调用,随后外层类的构造函数再调用,析构1的时候正好相反,外部类先析构,内部类再析构。
静态成员就是在成员变量前面加上static关键字,称为静态成员。
静态成员分为静态成员变量和静态成员函数。
。所有对象共享同一份数据
。在编译阶段分配内存。
。类内声明,类外初始化·静态成员函数
静态成员必须在类外初始化,否则编译器认为只声明,但是没有实际定义,链接发生错误。
代码:
- #include
- using namespace std;
- class person {
- public:
- static int age;
- };
- int person::age = 10;
- void fun() {
- person p;
- p.age = 90;
- person p1;
- cout << p1.age << endl;
- }
- int main() {
- fun();
- return 0;
- }
静态成员变量,不仅可以通过对象访问,也可以通过类名访问。静态成员变量也是有访问权限的。
代码:
- #include
- using namespace std;
- class person {
- public:
- static int age;
- };
- int person::age = 10;
- void fun() {
- person p;
- p.age = 90;
- cout << person::age << endl;
- }
- int main() {
- fun();
- return 0;
- }
。所有对象共享同一个函数
。静态成员函数只能访问静态成员变量
代码:
- #include
- using namespace std;
- class person {
- public:
- static int age;
- static void fun(int a) {
- age = a; //只能调用静态成员变量
- cout << "静态函数fun调用" << endl;
- }
- };
- int person::age = 100;
- void dioayong() {
- person p;
- p.fun(99); //对象调用
- person::fun(66); //类名调用
- cout << p.age << endl;
- }
- int main() {
- dioayong();
- return 0;
- }
同样,静态成员函数也是可以通过类名来调用,需要注意静态成员函数只能调用静态成员变量。
在C++中,类内的的成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象上
在C++中, 空类也占用一个字节。C++编译器会给每个空对象也分配一个字节空间,是为了区分对象占内存的位置。
代码:
- #include
- using namespace std;
- class person {
-
- };
- void fun() {
- person p;
- cout<<sizeof(p);
- }
- int main() {
- fun();
- return 0;
- }

在类中同样具有内存对齐的特性
代码:
- #include
- using namespace std;
- class person {
- public:
- int a;
- char b;
- };
- void fun() {
- person p;
- cout<<sizeof(p);
- }
- int main() {
- fun();
- return 0;
- }

此外,成员函数和静态成员变量都不存储在类上,也就是只有非静态成员变量存储在类中
代码:
- #include
- using namespace std;
- class person {
- public:
- int a;
- static int b;
- void fun() {
- cout << "fun函数调用" << endl;
- }
- static void fun1() {
- cout << "fun1函数调用" << endl;
- }
- };
- int person::b = 10;
- void fun() {
- person p;
- cout<<sizeof(p);
- }
- int main() {
- fun();
- return 0;
- }

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码那么问题是:这一块代码是如何区分那个对象调用自己的呢?
C++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象
注意:
1.this指针是隐含每一个非静态成员函教内的一种指针
2.this指针不需要定义,直接使用即可
this指针的用途:
·当形参和成员变量同名时,可用this指针来区分同名形参和变量
·在类的非静态成员函数中返回对象本身,可使用return *this
代码:
- #include
- using namespace std;
- class people {
- public:
- int age;
- people(int age) {
- this->age = age;
- }
- };
- void zhixing() {
- people p(10);
- cout << p.age << endl;
- }
- int main() {
- zhixing();
- return 0;
- }
返回自身时,注意要返回引用类型,返回普通值类型时,返回值是本身的副本
- #include
- using namespace std;
- class people {
- public:
- int age;
- people(int age) {
- this->age = age;
- }
- people& add(const people& p) {
- this->age += p.age;
- return *this;
- }
- };
- void zhixing() {
- people p1(10);
- people p2(20);
- p2.add(p1).add(p1).add(p1).add(p1);
- cout << p2.age << endl;
- }
- int main() {
- zhixing();
- return 0;
- }
C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针
代码:
- #include
- using namespace std;
- class person {
- public:
- int age;
- void fun1() {
- cout << "fun1调用" << endl;
- }
- void fun2() {
- cout << "fun2调用" << age << endl;
- }
-
- };
- void diaoyong() {
- person* p = NULL;
- p->fun1();
- p->age = 10;
- p->fun2();
- }
- int main() {
- diaoyong();
- return 0;
- }

只能成功调用没有this指针的函数,因为此时this是空指针,含有this的调用
代码:
- #include
- using namespace std;
- class person {
- public:
- int age;
- void fun1() {
- cout << "fun1调用" << endl;
- }
- void fun2() {
- if (this == NULL) {
- return;
- }
- cout << "fun2调用" << age << endl;
- }
-
- };
- void diaoyong() {
- person* p = NULL;
- p->fun1();
- p->fun2();
- }
- int main() {
- diaoyong();
- return 0;
- }
增加代码的健壮性,判断this指针是空指针的时候,跳出函数。
常函数:
1.成员函数后加const后我们称为这个函数为常函数。
2.常函数内不可以修改成员属性。
3.成员属性声明时加关键字mutable后,在常函数中依然可以修改。
常对象:
1.声明对象前加const称对象为常对象。
2.常对象只能调用常函数和用mutable修饰的成员变量。
this指针本质是指针常量,指针的指向是不可以修改的(person* const this),但是this指针指向地址的值是可以发生改变的。
常函数const要加在函数参数列表后面
代码:
- #include
- using namespace std;
- class person {
- public:
- int age;
- void showage(int m) const{
- // age = 89; //报错
- m = 100;
- cout << "age=" << age <<" m=" << m << endl;
- }
- };
- void fun() {
- person p;
- p.age = 10;
- p.showage(7);
- }
- int main() {
- fun();
- return 0;
- }

此时编译器会报错,此时age在函数内是不可改变的。但是函数传的参数,仍然是可以改变的。
- #include
- using namespace std;
- class person {
- public:
- mutable int age;
- void showage(int m) const{ //常函数
- age = 89; //报错
- m = 100;
- cout << "age=" << age <<" m=" << m << endl;
- }
- };
- void fun() {
- person p;
- p.age = 10;
- p.showage(7);
- }
- int main() {
- fun();
- return 0;
- }
成员属性声明时加关键字mutable后,在常函数中依然可以修改。
代码:
- #include
- using namespace std;
- class person {
- public:
- mutable int age;
- void showage1(int m) const{
- //age = 89; //报错
- m = 100;
- cout << "age=" << age <<" m=" << m << endl;
- }
- void showage2(int m) {
- age = 89;
- m = 100;
- cout << "age=" << age << " m=" << m << endl;
- }
- };
- void fun() {
- const person p;
- p.age = 10;
- p.showage1(7);
- //p.showage2(7); 报错
- }
- int main() {
- fun();
- return 0;
- }
常对象只能调用常函数和用mutable修饰的成员变量。普通函数和普通成员变量不能调用
友元关键字:friend
友元的三种实现:
1.全局函数做友元
2.类做友元
3.成员函数做友元
代码:
- #include
- using namespace std;
-
- class home {
- friend void func(home& p);
- public:
- home(string keting, string woshi, string cuosuo):keting(keting),woshi(woshi),cuosuo(cuosuo) {
-
- }
- string keting;
- private:
- string woshi;
- protected:
- string cuosuo;
- };
-
- void func(home &p) {
-
- cout << p.keting << ' ' << p.woshi << ' ' << p.cuosuo << endl;
- }
- void fun() {
- home p("客厅", "卧室", "厕所");
- func(p);
- }
- int main() {
- fun();
- //cout << p.keting << ' ' << p.woshi << ' ' << p.cuosuo << endl;
- //保护和私有属性的不能访问
- return 0;
- }

有元函数不是类的成员函数,但是却又权限调用类的所有成员变量
- #include
- using namespace std;
-
- class building {
- friend class goodgay; //声明友元类
- public:
- building();
- string keting;
- private:
- string cesuo;
- protected:
- string woshi;
- };
- building::building() {
- keting = "客厅";
- cesuo = "厕所";
- woshi = "卧室";
- }
-
- class goodgay {
- public:
- goodgay();
- void show();
- private:
- building* p;
- };
- void goodgay::show() {
- cout << this->p->keting << ' ' << this->p->cesuo << ' ' << this->p->woshi << endl;
- }
- goodgay::goodgay() {
- p = new building;
- }
- void f() {
- goodgay a;
- a.show();
- }
- int main() {
- f();
- return 0;
- }

类做友元,类中的所有成员函数都能访问友元类中所有成员。
代码:
- #include
- using namespace std;
- class building;
- class goodgay {
- public:
- goodgay();
- void show1(building& p);
- private:
- building* p;
- };
-
- class building {
- friend void goodgay::show1(building& p); //声明友元类
- public:
- building();
- string keting;
- private:
- string cesuo;
- protected:
- string woshi;
- };
- building::building() {
- keting = "客厅";
- cesuo = "厕所";
- woshi = "卧室";
- }
-
-
- void goodgay::show1(building& p1) {
- cout <
' ' << p1.cesuo << ' ' << p1.woshi << endl; - }
- //void goodgay::show2() {
- // cout << this->p->ketipng << ' ' << this->p->cesuo << ' ' << this->p->woshi << endl;
- //}
- //无权限
- goodgay::goodgay() {
- p = new building;
- }
- void f() {
- goodgay a;
- building b;
- a.show1(b);
- }
- int main() {
- f();
- return 0;
- }
注意类要先声明一下,防止报错,与全局函数做友元不同的是,要加上作用域。