C++中的继承
本博客中的所有代码来自于慕课网的实例(仅用作个人学习记录,侵权联系我本人)
首先我理解的继承就是为了定义更具体的东西时,不需要重新定义原本从最基本的数据(会从他原来的地方继承这些最基本的东西),只需要在定义中新加入的东西就可以。
把基类也就是被继承的类成为父类
把派生类也就是继承下来的类叫子类
继承方式也有几种
共有继承public 保护继承:protected 私有继承 private
通过子类继承父类,子类就会拥有父类所有的成员变量,通过成员函数就可以访问(该成员函数中如果涉及到从父类中继承过来的成员变量一定要注意类型是否可以被访问到)
当实例化子类的时候,编译时的函数调用顺序是
父类构造函数
子类构造函数
。。。。。
子类析构函数
父类析构函数
在赋值的时候可以将
1.子类对象赋值给父类对象(仅仅能赋值他俩都有的成员)
2.父类可以是子类的别名(仅仅能赋值他俩都有的成员)
3.父类指针指向子类对象(仅仅能赋值他俩都有的成员)
在参数传递时候同理也可以使用
有子类的类为什么析构函数一般设置成虚析构函数?
然后用父类指针在堆中实例化一个子类对象的时候,当最后想释放掉指针的时候只会调用父类的析构函数,导致了指针泄露,所以父类的析构函数一定要设置成虚析构函数。( virtual ~Person() ),这样的虚析构函数也可以被继承下去。
现在有三个函数
play(){
cout<<数据成员;
}
父类和子类中如果定义中默认构造函数中赋不同的时候。
test1(Person p){p.play()}
test2(Person *p){p->play()}
test3(Person &p){p.play()}
Person p;
Soldier s;
test1(p);//以下两行代码调用函数的顺序
test1(s);//父构造 父构造 子构造 play() 父析构 play() 父析构(创建了临时对象,退出临时对象时候分别会调用析构) 此处的两个play打印出来的数据并不一样,实参p打印出来的是父类默认构造函数赋的值,实参s打印出来的是子类默认构造函数赋的值。下面两组同理
test2(&p);//以下两行代码调用函数的顺序
test2(&s);//父构造 子构造 play() play()
test3(p); //以下两行代码调用函数的顺序
test3(s);//父构造 子构造 play() play()
隐藏
如果父类和子类中拥有同名的成员函数或者成员变量,在子类中进行函数调用的时候会默认调用子类中的成员变量和成员函数。例如两个类
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
/**
* 定义人类: Person
* 数据成员: m_strName
* 成员函数: attack()
*/
class Person
{
public:
string m_strName;
void attack()
{
cout << "attack" << endl;
}
};
/**
* 定义士兵类: Soldier
* 士兵类公有继承人类
* 数据成员: m_strName
* 成员函数: attack()
*/
class Soldier:public Person
{
public:
string m_strName;
void attack()
{
cout << "fire!!!" << endl;
}
};
int main(void)
{
// 实例士兵对象
Soldier soldier;
// 向士兵属性赋值"tomato"
soldier.m_strName = "tomato";
// 通过士兵对象向人类属性赋值"Jim"
soldier.Person::m_strName = "Jim";
// 打印士兵对象的属性值
cout << soldier.m_strName << endl;
// 通过士兵对象打印人类属性值
cout << soldier.Person::m_strName << endl;
// 调用士兵对象方法
soldier.attack();
// 通过士兵对象调用人类方法
soldier.Person::attack();
return 0;
}
多重继承和多继承
多重继承就是:爸爸继承爷爷,孙子又继承了爸爸。存在了一个多重关系。
多继承:就是某一个子类有多个父类,同时从很多父亲那里继承过来了很多事情。
例如多继承代码:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
/**
* 定义工人类: Worker
* 数据成员: m_strName
* 成员函数: work()
*/
class Worker
{
public:
Worker(string name)
{
m_strName = name;
cout << "Worker" << endl;
}
~Worker()
{
cout << "~Worker" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
}
protected:
string m_strName;
};
/**
* 定义儿童类: Children
* 数据成员: m_iAge
* 成员函数: play()
*/
class Children
{
public:
Children(int age)
{
m_iAge = age;
cout << "Children" << endl;
}
~Children()
{
cout << "~Children" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
}
protected:
int m_iAge;
};
/**
* 定义童工类: ChildLabourer
* 公有继承工人类和儿童类
*/
class ChildLabourer:public Worker,public Children
{
public:
ChildLabourer(string name, int age):Worker(name),Children(age)
{
cout << "ChildLabourer" << endl;
}
~ChildLabourer()
{
cout << "~ChildLabourer" << endl;
}
};
int main(void)
{
// 使用new关键字创建童工类对象
ChildLabourer *c=new ChildLabourer("hello",20);
// 通过童工对象调用父类的work()和play()方法
c->work();
c->play();
// 释放
delete c;
c=NULL;
return 0;
}
多重继承和多继承合在一起的时候BC都继承A (两组普通继承) D又继承BC(多继承)这个时候存在了ABD ACD两组多重继承,在D中会有两份A的成员。在编译的时候就会出现问题,解决的办法就是采用虚继承(BC继承A的时候加入虚想继承)
A:Person B: children C:Labourer D:ChildLabourer
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
/**
* 定义人类: Person
*/
class Person
{
public:
Person()
{
cout << "Person" << endl;
}
~Person()
{
cout << "~Person" << endl;
}
void eat()
{
cout << "eat" << endl;
}
};
/**
* 定义工人类: Worker
* 虚继承人类
*/
class Worker :virtual public Person
{
public:
Worker(string name)
{
m_strName = name;
cout << "Worker" << endl;
}
~Worker()
{
cout << "~Worker" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
}
protected:
string m_strName;
};
/**
* 定义儿童类:Children
* 虚继承人类
*/
class Children :virtual public Person
{
public:
Children(int age)
{
m_iAge = age;
cout << "Children" << endl;
}
~Children()
{
cout << "~Children" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
}
protected:
int m_iAge;
};
/**
* 定义童工类:ChildLabourer
* 公有继承工人类和儿童类
*/
class ChildLabourer:public Worker,public Children
{
public:
ChildLabourer(string name, int age):Worker(name),Children(age)
{
cout << "ChildLabourer" << endl;
}
~ChildLabourer()
{
cout << "~ChildLabourer" << endl;
}
};
int main(void)
{
// 用new关键字实例化童工类对象
ChildLabourer *p=new ChildLabourer("hello",123);
// 调用童工类对象各方法。
p->eat();
p->work();
p->play();
delete p;
p = NULL;
return 0;
}