首页 > 代码库 > 《21天C++》笔记之6月27日
《21天C++》笔记之6月27日
继承
- 公有继承,is-a的关系,比如,He is a man;
派生类可访问基类非私有成员,派生类实例也是;
- 私有继承和保护继承,has-a的关系,Car has a motor;
私有继承,也让派生类可访问基类非私有成员,但派生类实例无法访问基类任何成员,并且派生类的的子类也无法访问基类任何成员;
保护继承,与私有继承不同的是,子类的子类是可以访问基类的非私有成员;
注意:仅当必要时才使用私有或保护继承,遇到has-a情况时,尽量用组合或者聚合的方式替代(即将‘基类对象当作‘子类’‘的一个成员属性)
class Motor { public: void SwitchIgnition(); void PumpFuel(); void FireCylinders(); }; class Car { private: Motor heartOfCar; public: void Move() { heartOfCar.FireCylinders(); heartOfCar.PumpFuel(); heartOfCar.SwitchIgnition(); } };
- 切除:将子类对象显示复制给父类对象,或通过参数传递给父类对象,会只保留Base部分,这叫做切除
class Platypus:public Mammal,public Reptile,public Bird{};//多继承
- 重载,覆盖,隐藏:重载就是一个类里同名不同参数的函数,覆盖就是子类与父类同名同参数的函数,隐藏就是子类会将父类中同名但不同参数的函数隐藏,即实例不能访问。
多态
- 使用虚函数实现多态行为,通过引用或者指针调用虚函数即可实现多态
将派生类对象视为基类对象,并执行派生类的覆盖函数
class Fish { public: virtual void Swim() { cout << "Fish Swim.." << endl; } }; class Tuna : public Fish { public: virtual void Swim() { cout << "Tuna is fast" << endl; } }; class Carp : public Fish { public: virtual void Swim() { cout << "Carp is slow" << endl; } }; int main() { Tuna t; Carp c; Fish &f1 = t; f1.Swim(); return 0; }
- 对于使用new在自由存储区中实例化派生类对象,如果将其付给基类指针,
- 并通过该指针调用delete,将不会调用派生类的析构函数.
- 这可能会导致资源未释放,内存泄露等问题.
- 要避免这种问题,要将析构函数声明为虚函数.
class Fish { public: Fish() { cout <<"Constructed Fish"<< endl; } ~Fish() { cout << "Destroyed Fish" << endl; } }; class Tuna : public Fish { public: Tuna() { cout << "Constructed Tuna" <<endl; } ~Tuna() { cout << "Destroyed Tuna" << endl; } }; void DeleteFishMemory(Fish *pFish) { delete pFish; } int main() { Tuna *pTuna = new Tuna; DeleteFishMemory(pTuna); return 0; } /*输出: **Constructed Fish **Constructed Tuna **Destroyed Fish */
抽象基类与纯虚函数
不能被实例化的基类称为抽象基类,可通过声明纯虚函数创建.
class Fish { public: virtual void Swim() = 0; }; class Tuna : public Fish { public: void Swim() { cout << "Tuna swims fast in the sea " << endl; } };
使用虚继承解决菱形问题,(二义性)
class Animal { public: Animal() { cout << "ANimal constructor" << endl; } int Age; }; class Mammal:public virtual Animal { }; class Bird:public virtual Animal {}; class Reptile:public virtual Animal {}; class Platypus:public Mammal, public Bird, public Reptile { public: Platypus() { cout << "Platypus constructor" <<endl; } }; int main() { Platypus duckBilledp; duckBilledp.Age = 25; return 0; }
- 继承多个从同一个类派生而来的基类时,如果没有使用虚继承,将会继承多个基类的父类,而使用了虚继承,则只继承一个.
- virtual关键字有两个不同概念,一个是用于多态,另一个是用于虚继承解决二义性
从技术上说,C++不支持虚复制构造函数
运算符类型与运算符重载
- 单目运算符
1, (++)递增运算符
Date operator ++ (){} 单目前缀运算符在类中重载
Date operator ++ (int){}单目后缀运算符在类中重载
2, 转换运算符,下例是用转换运算符将Date转换为const char*
class Date { private: int Day; int Month; int Year; string DateInString; public: Date (int InputDay, int InputMonth, int InputYear) : Day(InputDay), Month(InputMonth), Year(InputYear) {} operator const char*() { ostringstream formattedDate; formattedDate << Day << " / " << Month << " / " << Year; DateInString = formattedDate.str(); return DateInString.c_str(); } }; int main() { Date Holiday (25, 12, 2011); cout << "Holiday is on: " << Holiday << endl; return 0; } //结果:Holiday is on: 25 / 12 / 2011
《21天C++》笔记之6月27日
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。