继承 (inherit )的使用与注意事项

来源:互联网 发布:网络主播怎么吸引粉丝 编辑:程序博客网 时间:2024/06/05 11:48

重点提示:并不是父类构造函数先执行再到子类的构造函数执行,而是子类的析构函数先执行,在子类的析构函数里再调用父类的析构函数。


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 : public Animal { // Human 继承了 Animal, 完全具有 Animal 类对象的功能
public:
void think() { // 扩展的功能
cout << "human think" << endl;
}
};
int main(void)
{
Human h;
h.eat();
h.think();
return 0;
}

注意:

1).继承时,父类的私有成员也是有继承过来的,只是子类不能直接访问父类的私有成员

2)一个对象 / 类型的大小,只算属性成员的大小,函数成员不算大小的。 同时也需注意它的祖先类的大小。
3)创建一个子类对象时,父类也需创建一个对象 , 子类对象是由父类对象与它自己的属性成员组合成的 .
4)友员的关系没有继承的

public 继承时 :

父类的公有成员在子类里的权限还是 public 的
父类的受保护成员在子类里的权限还是 protected 的
父类的私有成员在子类里不能直接访问
protected 继承 :
父类的公有成员在子类里的权限是 protected 的
父类的受保护成员在子类里的权限还是 protected 的
父类的私有成员在子类里不能直接访问private 继承 :
父类的公有成员在子类里的权限是 private 的
父类的受保护成员在子类里的权限是 private 的

父类的私有成员在子类里不能直接访问

可简化成以下表格:
继承方式\成员类型 public             protected     private
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;
}
编译执行时的输出:
[root@localhost 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 {

};



0 0
原创粉丝点击