C++学习系列笔记(四)

举报
小小谢先生 发表于 2022/04/16 01:40:27 2022/04/16
【摘要】 只能有一个实例的单例类 单例的概念使用私有构造函数、私有赋值函数和静态实例成员。要创建单例类,关键字static必不可少。重点知识点 参数是引用,如果不加&的话就是平常参数,也就是传值参数。传值参数,如果实参在函数中被修改时,外面的这个变量并不会改变。 引用参数,也就是在形参加上&,如果实参在函数中被修改的同时,外面的这...

只能有一个实例的单例类
单例的概念使用私有构造函数、私有赋值函数和静态实例成员。要创建单例类,关键字static必不可少。
重点知识点
参数是引用,如果不加&的话就是平常参数,也就是传值参数。传值参数,如果实参在函数中被修改时,外面的这个变量并不会改变。
引用参数,也就是在形参加上&,如果实参在函数中被修改的同时,外面的这个变量也会被修改。例:


  
  1. int a=10;
  2. void add1(int x)
  3. {
  4. x++;
  5. }
  6. add1(a);

执行完之后a还是10。


  
  1. int a=10;
  2. void add2(int &x)
  3. {
  4. x++;
  5. }
  6. add2(a);

执行完之后a=11。
禁止在栈中实例化的类
数据库类把析构函数设置为私有,只能使用new在自由储存区中创建其对象。如下代码:


  
  1. class MonsterDB
  2. {
  3. private:
  4. ~MonsterDB( ) {};
  5. public:
  6. static void DestroyInstance(MonsterDB* pInstance)
  7. {
  8. delete pInstance;
  9. }
  10. //……imagine a few other methods
  11. };
  12. int main()
  13. {
  14. MonsterDB* pMyDatabase = new MonsterDB();
  15. MonsterDB :: DestroyInstance(pMyDatabase);
  16. return 0;
  17. }

this指针
在类中,关键字this包含当前对象的地址,换句话说,其值为&object。
结构不同于类的地方
关键字struct来自于c语言,它与类极其相似。除非指定了,结构中的成员默认为公有,而类默认为私有;结构默认以公有方式继承,而类默认以私有方式继承。
4、声明友元函数
不能从外部访问类的私有数据成员和方法,但这条规则不适用于友元类和友元函数。要声明友元类和友元函数,可使用关键字friend,如下述所示。


  
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Human
  5. {
  6. private:
  7. string Name;
  8. int Age;
  9. friend void DisplayAge(const Human& Person);
  10. public:
  11. Human(string InputName, int InputAge)
  12. {
  13. Name = InputAge;
  14. Age = InputAge;
  15. }
  16. };
  17. void DisplayAge(const Human& person)
  18. {
  19. cout << person.Age << endl;
  20. }
  21. int main()
  22. {
  23. Human FirstMan("Adam", 25);
  24. cout << "Accessing private member age via:";
  25. DisplayAge(FirstMan);
  26. return 0;
  27. }

输出为:

Accessing private member age via:25

 

与函数一样,也可以将外部类指定为可信任的朋友。


  
  1. friend class Utility;
  2. class Utility
  3. {
  4. //code here;
  5. }

5、实现继承
基类比如鸟,将定义鸟的基本属性,如有羽毛和翅膀等等;派生类为乌鸦、鹦鹉等等将继承这些属性并进行定制。有些派生类能继承两个基类,这种称为多继承。
C++派生语法


  
  1. //declaring a super class
  2. class Base
  3. {
  4. //……base class members
  5. };
  6. //declaring a sub_class
  7. class Derived: acess-specifier Base
  8. {
  9. //……derived class members
  10. };

其中acess-specifier可以是public(这是最常见的,表示派生类是一个基类)、private或protected(表示派生类有一个基类)。
示例代码:


  
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Fish
  5. {
  6. public:
  7. bool FreshWaterFish;
  8. void Swim()
  9. {
  10. if (FreshWaterFish)
  11. cout << "swims in lake" << endl;
  12. else
  13. cout << "swims in sea" << endl;
  14. }
  15. };
  16. class Tuna :public Fish
  17. {
  18. public:
  19. Tuna()
  20. {
  21. FreshWaterFish = false;
  22. }
  23. };
  24. class Carp :public Fish
  25. {
  26. public:
  27. Carp()
  28. {
  29. FreshWaterFish = true;
  30. }
  31. };
  32. int main()
  33. {
  34. Carp myLunch;
  35. Tuna myDinner;
  36. cout << "my food to swim" << endl;
  37. cout << "lunch:";
  38. myLunch.Swim();
  39. cout << "Dinner:";
  40. myDinner.Swim();
  41. return 0;
  42. }

输出为:


  
  1. my food to swim
  2. lunch:swims in lake
  3. Dinner:swims in sea

访问限定符protected
将属性声明为protected时,相当于允许派生类和友元类访问他,但禁止在继承层次结构外部(包括main()访问他)。


  
  1. class Fish
  2. {
  3. protected:
  4. bool FreshWaterFish;
  5. //code here
  6. }

基类初始化——向基类传递参数。如下面代码所示:


  
  1. class Base
  2. {
  3. public:
  4. Base(int SomeNumber) //overload constructor
  5. {
  6. //Do Something with Somenumber
  7. }
  8. };
  9. class Derived : public Base
  10. {
  11. public:
  12. Derived(): Base(25) //instance class Base with argument 25
  13. {
  14. //derived class constructor code
  15. }
  16. };

上述代码改一下:


  
  1. //基类改一下
  2. public :
  3. Fish(bool IsFreshWater) : FreshWaterFish(IsFreshWater) {}
  4. //继承类Tuna改一下
  5. public:
  6. Tuna() : Fish(false) {}
  7. //继承类Carp改一下
  8. public:
  9. Carp() : Fish(true) {}

在派生类中覆盖基类的方法
如果派生类实现了从基类继承的函数,且返回值和特征值相同,就相当于覆盖了基类的方法,即派生类有一个和基类一模一样的函数,则程序运行是输出了派生类的函数结果。
调用基类中被覆盖的方法
1)如果要在main()中调用Fish::Swim(),需要使用作用域解析符(::)把上述的代码改一下就可以。


  
  1. //在Carp类中
  2. void Swim()
  3. {
  4. cout<<"Carp swims is too low"<<endl;
  5. Fish::Swim();
  6. }
  7. //在main()函数中
  8. cout<<"Dinner:";
  9. myDinner.Fish::Swim();

2)在Carp类中,使用关键字using解除对Fish::Swim()的隐藏


  
  1. //在Carp类中
  2. class Carp
  3. {
  4. public:
  5. using Fish::Swim; //去除基类隐藏的方法
  6. }

3)在Carp类中,覆盖Fish::Swim()的所有重载版本。
6、析构顺序和构造顺序

继承时,构造函数和析构函数的调用顺序
1、先调用父类的构造函数,再初始化成员,最后调用自己的构造函数
2、先调用自己的析构函数,再析构成员,最后调用父类的析构函数
3、如果父类定义了有参数的构造函数,则自己也必须自定义带参数的构造函数
4、父类的构造函数必须是参数列表形式的
5、多继承时,class D: public Base2, Base1, Base的含义是:class D: public Base2, private Base1, private Base,而不是class D: publicBase2, public Base1, public Base6.多继承时,调用顺序取决于class D: public Base2, public Base1, public Base的顺序,也就是先调用Base2,再Base1,再Base。但是有虚继承的时候,虚继承的构造函数是最优先被调用的。
私有继承:private
即便是Base类的公有成员和方法,也只能被Derived类使用,而无法通过Derived实例来使用他们。
保护继承:protected
保护继承与私有继承的相似之处:
1)他也表示has-a关系
2)他也让派生类能够访问基类的所有公类和保护成员
3)在继承结构层次外面,也不能通过派生类实例访问基类的公有成员
随着继承结构的加深,保护继承与私有继承有些不同


  
  1. class Derived2:protected Derived
  2. {
  3. //can acess menber of Base
  4. };

在保护继承层次结构中,子类的子类(Derived)能够访问Base类的公有成员。
将Base类作为子类的私有成员被称为组合或聚合,如下面代码所示:


  
  1. class Car
  2. {
  3. private:
  4. Motor heartOfcar;
  5. public:
  6. void Move()
  7. {
  8. heartOfca.SwitchInginition();
  9. //code here;
  10. ]
  11. ];

这能够轻松在Car类中添加Motor成员而无需改变继承结构层次
7、切除问题


  
  1. Derived objectDerived;
  2. Base objectBase = objectDerived;

或者:


  
  1. void FunuseBase(Base Input)
  2. ……
  3. Derived objectDerived;
  4. FunuseBase(objectDerived);

上述代码都将Derived对象复制给Base对象,一个是显示复制,一个是通过传递函数。在这种情况下,编译器将只会复制objectDerived的Base部分,即不是整个对象,而是Base能容纳的部分。这种无意间裁剪数据,导致Derived变成Base的行为称为切除(slice)
8、多继承
C++允许继承多个基类


  
  1. class Derived : acess-specifier Base1,cess-specifier Base2,……
  2. {
  3. //class menbers
  4. };

文章来源: blog.csdn.net,作者:小小谢先生,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/xiewenrui1996/article/details/90732878

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。