10--C++中的继承
来源:互联网 发布:apache 隐藏index.php 编辑:程序博客网 时间:2024/04/27 16:06
一.继承的概念
*:子类拥有父类的所有的成员变量和成员函数
*: 子类就是一种特殊的父类
*: 子类对象可以当做父类对象使用
*: 子类可以拥有父类没有的方法和属性
注意:(1)C++中class的继承默认为private继承
(2)private继承的子类拥有父类的所有成员
(3)private继承使得父类的所有成员在子类中变成private成员
二.C++中的访问级别与继承
*: public
父类成员在子类中保持原有访问级别
*: private继承
父类成员在子类中变为private成员
*:类的 protected 成员
(1)protected成员可以在子类中被访问,但是不能在外界访问。
(2)protected成员的访问权限介于 public 和 private 之间
class Parent{//private: /// 若为私有,编译不通过 protected:int a;public:Parent(){a = 100;}void print(){cout<<"a="<<a<<endl; }};class Child:public Parent{private:int b;public:void set(int a,int b){this->a =a;this->b =b;}};
类成员访问级别设置的原则
*: 需要被外界访问的成员直接设置为 public
*: 只能在当前类中访问的成员设置为 private
*: 只能在当前类中和子类中访问的成员设置为 protected
注意: private 成员在子类中依然存在,但是却无法访问到。
即使私有继承:
Parent p;Child c;cout<<sizeof(p)<<" "<<sizeof(c)<<endl;
公式: 继承成员对外的访问属性
={继承方式,父类成员访问级别}
三. 赋值兼容性原则
*: 子类对象可以当做父类对象使用
*: 子类对象可以直接赋值给父类对象
*: 子类对象可以直接初始化父类对象
*: 父类指针可以直接指向子类对象
*: 父类引用可以直接引用子类对象
示例:
#include <cstdlib>#include <iostream>using namespace std;class Parent{protected: const char* name;public: Parent() { name = "Parent"; } void print() { cout<<"Name: "<<name<<endl; }};class Child : public Parent{protected: int i;public: Child(int i) { this->name = "Child"; this->i = i; }};int main(int argc, char *argv[]){ Child child(1000); Parent parent = child;//父类对象 Parent* pp = &child; // 父类指针 Parent& rp = child; // 父类引用 parent.print(); pp->print(); rp.print(); return 0;}
类在C++编译器内部可以理解为结构体
*: 子类是有父类成员叠加子类新成员得到的
四. 继承与构造
在子类对象构造的时候需要调用父类构造函数,对其继承得来的成员进行初始化
五.继承与析构
在子类对象析构的时候需要调用父类析构函数对其继承得来的成员进行清理
示例:
#include <stdio.h>#include <iostream>using namespace std;class Parent{public:Parent(const char* s){cout<<"Parent()"<<" "<<s<<endl;}~Parent(){cout<<"~Parent()"<<endl;}};class Child:public Parent{public:Child():Parent("init from child!"){cout<<"Child()"<<endl;}~Child(){cout<<"~Child()"<<endl;}};int main(){Child child;return 0;}
说明:
(1)子类对象在创建时会首先调用父类的构造函数(2)父类构造函数执行结束后,在调用子类的构造函数
(3)当父类的构造函数有参数时,需要在子类的初始化表中显式调用
(4)析构函数调用的先后顺序与构造函数相反
六. 继承与组合的混搭
类中的成员变量可以是其他类的对象。
#include <stdio.h>#include <iostream>using namespace std;class Object{public:Object(const char* s){cout<<"Object()"<<" "<<s<<endl;}};class Parent:public Object{public:Parent(const char* s):Object(s){cout<<"Parent()"<<" "<<s<<endl;}};class Child:public Parent{protected:Object o1;Object o2;public:Child():o2("o2"),o1("o1"),Parent("from child"){cout<<"Child()"<<endl;}};int main(){Child child;return 0;}
七. 同名成员变量
当子类成员变量与父类成员变量同名时
*: 子类依然从父类继承同名成员
*: 在子类中通过作用域分辨符:: 进行同名成员区分
*: 同名成员存储在内存中的不同位置
#include <stdio.h>#include <iostream>using namespace std;class Parent{public:int i;int f;};class Child:public Parent{protected:int i;public:Child(int i,int j){Parent::i=i;Child::i=j;Parent::f= i+j;f();}void f(){cout<<"Parent::i= "<<Parent::i<<endl;cout<<"Child::i= "<<Child::i<<endl;cout<<"Parent::f= "<<Parent::f<<endl;}};int main(){Child child(1,3);return 0;}
总结:
(1)继承是一种类之间的关系,子类是一种特殊的父类
(2)子类通过继承可以得到父类的所有成员
(3)private 成员可以被子类类继承但不能被子类访问
(4)protected 成员只能在当前的类和子类中被访问
(5)不同的继承方式可能改变继承成员的访问属性
(6)子类对象可以当做父类对象使用
(7)子类对象在创建时需要调用父类构造函数进行初始化
(8)子类对象在销毁时需要调用父类析构函数进行清理
(9)先执行父类构造函数,再执行子类成员构造函数
(10)在继承中的析构顺序与构造顺序对称相反
(11)同名成员通过作用域分辨符进行区分
- 【C++】c++中的继承
- 浅谈Objective-C中的继承
- 【C++】浅谈C++中的继承
- 【C++】浅析C++中的继承
- 10--C++中的继承
- 【C++】:C++中的继承权限和继承方式
- 初识c#---继承和继承关系中的构造函数
- C中的继承和多态
- C#中的接口和继承多态
- C中的继承与多态
- Objective-C中的继承和重载
- C中的继承和多态
- C++:多继承中的二义性问题
- Objective-C中的继承与复合技术
- C中的继承和多态
- C中的继承和多态
- C中的继承和多态
- C中的继承和多态
- 归并排序和求逆序数
- Codeforces Round #266 (Div. 2)(good)
- 对比iOS网络组件:AFNetworking VS ASIHTTPRequest
- 约瑟夫问题 双链表实现
- 正弦与余弦
- 10--C++中的继承
- linux python实现data matrix 二维码显示和处理
- Javascript中的块级作用域
- Count and Say
- 成功在WIN2003上安装oracle8.1.7(转)
- PHP匿名和闭包函数
- STM32驱动DS18B20
- 找出带环单向链表的环入口(交点)
- 四川大学线下编程比赛第三题:书本转移