继承,多重继承与虚继承
1.继承其实就是在一个类的基础上扩展新的功能的类型。
#include <iostream>
using namespace std;
class Animal {
private:
int age;
public:
void eat() {
age = 88;
cout <<"animal eat" << endl;
};
};
// Animal叫作Human的父类, Human是Animal的子类
// 继承是可以多层继承的,基类是最底层的类。 子类的子类以下级别的类叫派生类.
class Human : publicAnimal { // Human继承了Animal,完全具有Animal类对象的功能
public:
void think() { //扩展的功能
cout <<"human think" << endl;
}
};
int main(void)
{
Human h;
h.eat();
h.think();
return 0;
}
注意:继承时,父类的私有成员也是有继承过来的,只是子类不能直接访问父类的私有成员
一个对象/类型的大小,只算属性成员的大小,函数成员不算大小的。同时也需注意它的祖先类的大小。
创建一个子类对象时,父类也需创建一个对象,子类对象是由父类对象与它自己的属性成员组合成的.
友员的关系没有继承的
public继承时:
父类的公有成员在子类里的权限还是public的
父类的受保护成员在子类里的权限还是protected的
父类的私有成员在子类里不能直接访问
protected继承:
父类的公有成员在子类里的权限是protected的
父类的受保护成员在子类里的权限还是protected的
父类的私有成员在子类里不能直接访问
private继承:
父类的公有成员在子类里的权限是private的
父类的受保护成员在子类里的权限是private的
父类的私有成员在子类里不能直接访问
2.继承时,创建子类对象时也会创建它的父类对象。子类和父类的构造函数都会触发.
#include <iostream>
using namespace std;
class Animal {
public:
Animal() {
cout << "animal init " << endl;
}
~Animal() {
cout << "animal exit " << endl;
}
};
class Human : public Animal {
public:
Human() {
cout << "human init " << endl;
}
~Human() {
cout << "human exit " << endl;
}
};
int main(void)
{
Human *h;
h = new Human;
cout << "#################" << endl;
delete h;
return 0;
}
编译执行时的输出:
[[email protected] 11inherit]# ./a.out
animal init
human init
#################
human exit
animal exit
从表面上看当创建对象时,父类构造先执行,然后才是子类的构造函数执行。
反汇编来看,可以发现其实是子类的构造函数先执行,在子类的构造函数里再调父类的构造函数.
子类的析构函数先执行,在子类的析构函数里再调用父类的析构函数.
当父类的构造函数必须传参数时,必须在子类的构造函数的函数体加上”: 父类构造函数名(参数)”来调用父类的构造函数.
class Animal {
private:
int num;
public:
Animal(int num) {
this->num = num;
cout << "animal init num = " << num <<endl;
}
~Animal() {
cout << "animal exit " << endl;
}
};
class Human : public Animal {
private:
int hh;
public:
Human(int num, int n) : hh(n), Animal(num){
cout << "human init hh = " << hh <<endl;
}
~Human() {
cout << "human exit " << endl;
}
};
int main(void)
{
Human *h;
h = new Human(123, 7788);
cout << "#################" << endl;
delete h;
return 0;
}
构造函数的”:”可以调用父类的构造函数(只能调用父类的构造函数,不能越级), 也可以用于内部属性成员进行初始化.
3. 多重继承
通过继承多个父类扩展出一个新的类型。
class AA {
...
};
class BB {
..
};
class AB : public AA, public BB {
...
};
多重继承也会带来新的问题,如下代码:
//基类
class Object {
public:
Object() {
cout << "object init" << endl;
}
};
class A : public Object {
//当创建A的对象时,Object也需创建一个对象
};
class B : public Object {
//当创建B的对象时,Object也需创建一个对象
};
class AB : public A, public B {
//创建AB的对象时,A和B都需要创建一个对象,但会有两个Object对象
};
int main(void)
{
AB a;
return 0;
}
要解决重复创建同一基类的对象时,可以使用虚继承.
Class A : virtual public Object {
};
Class B : virtual public Object {
};
本文由广州尚观科技发布。
1.继承其实就是在一个类的基础上扩展新的功能的类型。
#include <iostream>
using namespace std;
class Animal {
private:
int age;
public:
void eat() {
age = 88;
cout <<"animal eat" << endl;
};
};
// Animal叫作Human的父类, Human是Animal的子类
// 继承是可以多层继承的,基类是最底层的类。 子类的子类以下级别的类叫派生类.
class Human : publicAnimal { // Human继承了Animal,完全具有Animal类对象的功能
public:
void think() { //扩展的功能
cout <<"human think" << endl;
}
};
int main(void)
{
Human h;
h.eat();
h.think();
return 0;
}
注意:继承时,父类的私有成员也是有继承过来的,只是子类不能直接访问父类的私有成员
一个对象/类型的大小,只算属性成员的大小,函数成员不算大小的。同时也需注意它的祖先类的大小。
创建一个子类对象时,父类也需创建一个对象,子类对象是由父类对象与它自己的属性成员组合成的.
友员的关系没有继承的
public继承时:
父类的公有成员在子类里的权限还是public的
父类的受保护成员在子类里的权限还是protected的
父类的私有成员在子类里不能直接访问
protected继承:
父类的公有成员在子类里的权限是protected的
父类的受保护成员在子类里的权限还是protected的
父类的私有成员在子类里不能直接访问
private继承:
父类的公有成员在子类里的权限是private的
父类的受保护成员在子类里的权限是private的
父类的私有成员在子类里不能直接访问
2.继承时,创建子类对象时也会创建它的父类对象。子类和父类的构造函数都会触发.
#include <iostream>
using namespace std;
class Animal {
public:
Animal() {
cout << "animal init " << endl;
}
~Animal() {
cout << "animal exit " << endl;
}
};
class Human : public Animal {
public:
Human() {
cout << "human init " << endl;
}
~Human() {
cout << "human exit " << endl;
}
};
int main(void)
{
Human *h;
h = new Human;
cout << "#################" << endl;
delete h;
return 0;
}
编译执行时的输出:
[[email protected] 11inherit]# ./a.out
animal init
human init
#################
human exit
animal exit
从表面上看当创建对象时,父类构造先执行,然后才是子类的构造函数执行。
反汇编来看,可以发现其实是子类的构造函数先执行,在子类的构造函数里再调父类的构造函数.
子类的析构函数先执行,在子类的析构函数里再调用父类的析构函数.
当父类的构造函数必须传参数时,必须在子类的构造函数的函数体加上”: 父类构造函数名(参数)”来调用父类的构造函数.
class Animal {
private:
int num;
public:
Animal(int num) {
this->num = num;
cout << "animal init num = " << num <<endl;
}
~Animal() {
cout << "animal exit " << endl;
}
};
class Human : public Animal {
private:
int hh;
public:
Human(int num, int n) : hh(n), Animal(num){
cout << "human init hh = " << hh <<endl;
}
~Human() {
cout << "human exit " << endl;
}
};
int main(void)
{
Human *h;
h = new Human(123, 7788);
cout << "#################" << endl;
delete h;
return 0;
}
构造函数的”:”可以调用父类的构造函数(只能调用父类的构造函数,不能越级), 也可以用于内部属性成员进行初始化.
3. 多重继承
通过继承多个父类扩展出一个新的类型。
class AA {
...
};
class BB {
..
};
class AB : public AA, public BB {
...
};
多重继承也会带来新的问题,如下代码:
//基类
class Object {
public:
Object() {
cout << "object init" << endl;
}
};
class A : public Object {
//当创建A的对象时,Object也需创建一个对象
};
class B : public Object {
//当创建B的对象时,Object也需创建一个对象
};
class AB : public A, public B {
//创建AB的对象时,A和B都需要创建一个对象,但会有两个Object对象
};
int main(void)
{
AB a;
return 0;
}
要解决重复创建同一基类的对象时,可以使用虚继承.
Class A : virtual public Object {
};
Class B : virtual public Object {
};
本文由广州尚观科技发布。