C++继承
来源:互联网 发布:韩子高网络剧下百度云 编辑:程序博客网 时间:2024/05/29 19:00
在定义对象时,可以发现很多对象都是有联系的,如以下的两个类,worker中的一些成员也是person的成员,应对这种情况,减轻程序员的工作量,C++设计了继承。
class Person{public:void eat();string m_strName;int m_iAge;};class Worker{public:void eat();void work();string m_strName;int m_iAge;int m_iSalary;};
有了继承,我们可以把worker的类写成这样,不用再把person类中已有的成员再写一遍。worker是person的派生类,person是worker的基类。
class Worker:public Person{public:void work();int m_iSalary;};当我们实例化一个派生类的对象时,会先构造基类,再构造派生类,而析构时顺序相反,运行的顺序如下。
Person();
Worker();
~Worker();
~Person();
C++的继承方式有三种。
class A: public B //公有继承
class A:protected B//保护继承
class A:private B//私有继承
protected在不涉及继承时,特性和private的性质是一样的。
class Person{public:Person();//构造函数~Person();//析构函数void eat(); protected:int m_iAge;private:string m_strName;};当做如下访问时,会出现错误。因为不在public下面。
int main(){Person person;person.eat();person.m_iAge = 20;//错误person.m_strName = "jim";//错误return 0;}
class Person{public:Person();//构造函数~Person();//析构函数void eat(); protected:int m_iAge;string m_strName;};
class Worker :public Person//公有继承{public:Worker();//构造~Worker();//析构void eat();//继承person的void work(){ m_iAge = 20; }protected:string m_strName;//继承personint m_iAge;//继承personint m_iSalary;};
private的继承特性,如果将protected改为private。代码如下。
class Person{public:Person();//构造函数~Person();//析构函数void eat(); private:int m_iAge;string m_strName;};class Worker :public Person//公有继承{public:Worker();//构造~Worker();//析构void eat();//继承person的void work(){ m_iAge = 20; }//这样访问错误protected://private中的m_strName和m_iAge被继承到了不可见位置int m_iSalary;};
保护继承,基类的public和protected的成员都会被继承到派生类的protected下面,而private还是无法被访问。
私有继承,基类的public和protected的成员都会被继承到派生类的private下面,而private还是无法被访问。
C++有两个很容易混淆的概念,覆盖和隐藏。什么是隐藏,加入B是A的派生类,两个类有相同函数名的成员函数,比如void ABC(),这时,子类中的void ABC()会自动隐藏父类中的void ABC(),但并没有消失,可以通过特殊的手段访问,数据成员也有隐藏这种现象。
在继承中,派生类的对象可以复制给基类,也可以用基类的指针指向派生类的对象,反之不可以。但基类还是无法访问子类中特有的成员函数和成员数据。如果销毁时,只调用了基类的析构函数,而没有调用派生类的,那么就会有一些内存没有删干净。为了防止这种现象,就会用到虚析构函数。
当有继承关系时,用父类的指针指向堆中子类对象,并且想用父类的指针来释放掉这块内存,那么要用到虚析构函数,那么在释放内存时,会依次调用子类的析构和父类的析构函数。
class Person{public:Person();//构造函数virtual ~Person();//析构函数void play(); private:int m_iAge;string m_strName;};
多重继承,比如有三个类,人类-士兵类-步兵类,三个依次继承,那么就成为多重继承。
class Person{};class Soldier :public Person{};class Infantryman :public Soldier{};
多继承,如果有一个类有多个基类,如农民工类集成了农民类和工人类。
class Worker{};class Farmer{};class MigrantWorker:public Worker,public Farmer{};
在实际中,会出现菱形继承的情况,就是D继承了B和C类,B和C都是A的派生类,既包含了多继承又包含了多重继承,我们在实例化D,就会继承两个A的成员,造成数据的冗余,为了解决这种现象,就用虚继承的方式。如果B和C是虚继承A的话,那么实例化D后,D中只有一份A的数据成员,不会冗余。
class Worker :virtual public Person// 虚基类{};class Farmer :virtual public Farmer{};当我们在基类定义时加上virtual时,那么继承的农民工类在实例化时,就只有一份person的数据了。
重定义,就是指在当前的工程中,一个类被定义了两遍,只在多个继承类的.h文件中,多次引用了 基类.h的文件,这就出现了重定义。通过宏定义解决重定义。
首先,在公共继承的类中增加宏定义。在菱形继承中,重定义必然会出现。
#ifndef PERSON_H#define PERSON_H/*******文件体************/#endif
- c继承
- C++----------------继承
- 【c#】继承
- C++:继承
- C++::继承
- [C++]继承
- 【C++】继承
- 【C#】继承
- 【c++】继承
- 【C++】继承
- c#-继承
- 【C++】 继承
- 【C#】继承
- C++|继承
- 【C++】继承
- C/C++--私有继承
- [C/C++]继承
- c++:私有继承,公有继承,保护继承
- html5
- Java的各种排序算法详解
- eng
- StringBuffer和StringBuilder的区别
- cocos2dx Action 特效
- C++继承
- shell
- ZJNU acm 共469题AC代码
- Makefile
- C# delegate多种变体
- Android :uses-feature和uses-permission的关系和区别
- LeetCode : Remove Element [java]
- qt
- 1090. Highest Price in Supply Chain (25)