总结:

1、子类对象可以当做父类对象使用
2、子类对象可以直接赋值给父类对象
3、子类对象能够直接初始化父类对象
4、父类指针可以直接指向子类对象
5、凡是继承过来的属性和函数都可以在子类中用this->  进行访问
6、默认构造函数并不会初始化数据成员
7、如果子类数据成员和父类数据成员名称相同。在子类用利用:: 访问父类数据成员,this-> 默认为子类数据成员

8、构造函数和析构函数不会被继承

一、类型兼容性规则

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。

类型兼容规则中所指的替代包括以下情况:

<1>子类对象可以当作父类对象使用

<2>子类对象可以直接赋值给父类对象

<3>子类对象可以直接初始化父类对象

<4>父类指针可以直接指向子类对象

<5>父类引用可以直接引用子类对象

继承模型:

在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化.

在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理.

二、继承中构造析构调用原则

1、子类对象在创建时会首先调用父类的构造函数

2、父类构造函数执行结束后,执行子类的构造函数

3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用

4、析构函数调用的先后顺序与构造函数相反

总原则:

先构造父类,再构造成员变量、最后构造自己

                      先析构自己,在析构成员变量、最后析构父类

三、继承中同名成员变量处理方法

1、当子类成员变量与父类成员变量同名时 ,子类依然从父类继承同名成员

2、在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式地使用类名限定符)

注:同名成员存储在内存中的不同位置

四、派生类中的static关键字

1、基类定义的静态成员,将被所有派生类共享

2、根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)

3、 派生类中访问静态成员,用以下形式显式说明:

类名 :: 成员

或通过对象访问      对象名 . 成员

示例:

1、类的兼容性规则

#if 1
#include<iostream>
using namespace std;class Parent {
public:void printP() {cout << "a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:/*void printP() {cout << "b:" << this->b << endl;}*/void printC() {cout << "b:" << this->b << endl;}int b;
};
void test01() {Parent *p = new Child;p->printP();  //子类和父类都有printP函数时,调用父类的成员函数
}
//子类对象可以当做父类对象使用
//子类对象可以直接赋值给父类对象
//子类对象能够直接初始化父类对象
void test02() {Parent p;  //父类空间小//Child c = p; //子类空间大于父类,不能够全部初始化,所以报错Child c;Parent p = c;  //c对象占用空间>=p对象占用空间 //能够填充可以通过编译//子类对象能够直接初始化父类对象c.printP();  //c能够当做父类p来使用}
//父类指针可以直接指向子类对象
//好处:
void test03() {Parent *pp = NULL;  //父类指针Child *cp = NULL;   //子类指针Parent p;  //父类对象Child c;   //子类对象cp = &c;//cp = &p;  子类指针指向父类对象 错误 子类指针访问范围大于父类对象的范围//原来cp的访问权限为cp->a,cp->b,cp->printP.cp->printC//cp指向p时,cp的访问权限只能为cp->a,cp->printP//会访问越界pp = &p;pp = &c;  //通过编译 父类指针指向子类对象//原来cp的访问权限为pp->a; pp->printP//pp指向c时,cp的访问权限扔为pp->a; pp->printP//c内存布局能够满足父类指针的全部需求  可以用一个儿子的对象地址给父类指针赋值}
int main() {return 0;
}
#endif

2、构造函数和析构函数

#if 0
#include<iostream>
using namespace std;
//在调用子类的构造函数时  一定会调用父类的构造函数
//父类先构造,子类再构造
//析构和构造顺序相反
class Parent {
public:Parent() {cout << "Parent()... " << endl;a = 0;}Parent(int a) {cout << "Parent(int a)..." << endl;this->a = a;}int a;~Parent() {cout << "~Parent()..." << endl;}
};
class Child :public Parent {
public://在调用子类的构造函数时  编译器会默认调用父类无参构造
#if 0Child(int a,int b) {cout << "Child(int a,int b)..." << endl;this->a = a;this->b = b;}
#endif//显示调用父类有参构造Child(int a ,int b):Parent(a){cout << "Child(int a,int b)..." << endl;this->b = b;}~Child() {cout << "~Child()... " << endl;}void printC() {cout << "b=" << b << endl;}int b;
};//在调用子类时 编译器会默认调用父类无参构造
void test01() {Child c(10, 20);c.printC();
}
/*
Parent()...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
//显示调用父类有参构造
void test02() {Child c(10, 20);c.printC();
}
/*
Parent(int a)...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
int main() {test01();return 0;
}
#endif

3、子类和父类成员重名

#if 0
#include<iostream>
using namespace std;
#if 0
class Parent {
public:Parent() {cout << "Parent() " << endl;this->a = 0;}Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int a) {cout << "Child(int a)" << endl;this->a = a;}~Child() {cout << "析构子类a:" << this->a << endl;}
};void test01() {Child c(2);
}
/*
Parent()
Child(int a)
析构子类a:2
析构父类a:0
*/
#endif
#if 0
class Parent {
public:Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int p_a,int c_a):Parent(p_a){cout << "Child(int a)" << endl;this->a = c_a;}~Child() {cout << "析构子类a:" << this->a << endl;}void print() {cout << "父类a:"<<Parent::a << endl;cout <<"子类a:" <<this->a << endl;  //子类的a}
};void test01() {Child c(2,3);c.print();
}
/*
Parent(int a)
Child(int a)
父类a:2
子类a:3
析构子类a:3
析构父类a:2
*/
#endif
//子类和父类函数名相同调用
class Parent {
public:Parent(int a) {cout << "Parent(int a) " << endl;this->a = a;}void print() {cout << "父类print" <<  endl;}~Parent() {cout << "析构父类a:" << this->a << endl;}int a;
};
class Child :public Parent {
public:int a;Child(int p_a, int c_a) :Parent(p_a) {cout << "Child(int a)" << endl;this->a = c_a;}~Child() {cout << "析构子类a:" << this->a << endl;}void print() {cout << "子类print" << endl;  //子类的a}
};void test01() {Parent p(1);p.print();cout << "------" << endl;Child c(2, 3);c.Parent::print();c.print();
}
/*
Parent(int a)
父类print
------
Parent(int a)
Child(int a)
父类print
子类print
析构子类a:3
析构父类a:2
析构父类a:1
*/
int main() {test01();return 0;
}
#endif

4、继承中的static成员

#if 1
#include<iostream>
using namespace std;
#if 0
class A {
public:static int a;
private:
};
int A::a = 0;  //静态成员变量 初始化void test01()
{A a1;A a2;cout << a1.a << endl;cout << a2.a << endl;a1.a = 300;cout << a1.a << endl;cout << a2.a << endl;
}
/*
0
0
300
300
*/
#endifclass A {
public:static int a;
private:
};
class B :public A {
public:
private:
};
int A::a = 0;  //静态成员变量 初始化void test01()
{A a1;A a2;cout << a1.a << endl;cout << a2.a << endl;a1.a = 300;cout << a1.a << endl;cout << a2.a << endl;B b1;B b2;cout << b1.a << endl;cout << b2.a << endl;A::a = 400;cout << b1.a << endl;cout << b2.a << endl;
}
/*
0
0
300
300
300
300
400
400
*/
int main() {test01();return 0;
}
#endif

C++基础13-类和对象之继承2相关推荐

  1. 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法

    python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...

  2. JAVA基础七 类和对象

    文章目录 JAVA基础七 类和对象 01 引用 02 继承 03 方法重载 04 构造方法 05 this 06 传参 07 包 08 访问修饰符 09 类属性 10 类方法 11 属性初始化 12 ...

  3. Racket编程指南——13 类和对象

    13 类和对象 本章基于一篇论文[Flatt06]. 一个类(class)表达式表示一类值,就像一个lambda表达式一样: (class superclass-expr decl-or-expr . ...

  4. c++入门(类和对象and继承)

    文件名:<1> time.h :<2> time.cpp :<3> DateTime.h :<4> DateTime.cpp :<5> ma ...

  5. java基础(类与对象、集合)

    java基础(类与对象.集合) 类与对象 类与对象中的栈和堆 构造方法 this关键字 面向对象三大特性 封装性(private) 继承性(extends) 方法重写(@override) 多态性 向 ...

  6. python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态

    六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...

  7. JAVA基础––从类和对象开始

    JAVA基础--从类和对象开始 一.概念 1.面向对象中类和对象的概念 对象:对象是具有状态和行为的实体,例如某个具体的学生,或者是王者荣耀里的英雄,可以是物理实体,也可以是逻辑实体. 类:类是一组具 ...

  8. Java_面向对象基础(类、对象、方法和构造函数)

    Java的面向对象基础(类.对象.方法和构造函数) 面向对象的基本概念 面向对象的设计思想 什么是类 什么是对象 类的定义 设计面向对象的例子 步骤一:设计动物这个类 步骤二:创建具体的动物 步骤三: ...

  9. python入门笔记——类和对象⑤(继承)

    python入门笔记--类和对象⑤(继承) # python中展现面向对象的三大特征:封装.继承.多态 # 封装:把内容封装到某个地方以便后续的使用 # 对封装来说,其实就是使用初始化构造方法将内容封 ...

  10. 【C++基础】类和对象——友元

    [C++基础]类和对象--友元 友元的概念 在C++中,不能被外部访问的私有属性,通过友元可以访问. 友元的关键字:friend 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 一.全局函数 ...

最新文章

  1. qdockwidget设置隐藏标题栏,重叠时tab标签位置,自动填充满整个窗口
  2. 后盾网php多少钱_复合排水网价格多少钱
  3. 关于delete和delete[]
  4. python跟java 效率_Python与Java:哪个更好,如何选择?
  5. java 手势识别,AndroidStudio:手势识别
  6. Linux命令:find命令详解
  7. C# EntityFramework连接MySQL (DbFirst)
  8. 多功能计算机如何关闭,多功能的计算机显示终端
  9. Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理
  10. 公共代码参考(DisplayMetrics)
  11. AE Pixel Sorter 2 for Mac破解教程
  12. php毕设周记,毕设周记录如何写的
  13. 怎么有效的管理微信群?分享3点有用的经验
  14. 设计思维(Design Thinking)
  15. 发送ajax将浏览器卡死,jQuery Ajax同步参数致使浏览器假死怎么办
  16. K8s 之 ReadinessProbe(就绪探针)使用的迷惑
  17. 解决Python下安装unrar后仍然提示Couldn't find path to unrar library...
  18. JSP设置Excel表格换行_如何在WPS-Excel表格中设置可爱的“温馨提示”?
  19. Chrome浏览器运行超图三维场景
  20. 报错:npm ERR code EPERM

热门文章

  1. 学习Spring Boot:(十八)Spring Boot 中session共享
  2. Java 单例模式:懒加载(延迟加载)和即时加载
  3. JAVA分布式篇1——Linux
  4. springboot2稳定版本_重要版本Spring Boot 2.3.0发布 - spring.io
  5. 数控车椭圆编程实例带图_数控车床编程教程,图文实例详解
  6. php字符串中单引号与双引号的区别,简单概括PHP的字符串中单引号与双引号的区别...
  7. aqs clh java_【Java并发编程实战】----- AQS(一):简介
  8. mac os11以下安装Xcode
  9. python3中的 input函数_Python3中的input函数
  10. MySql主从同步最小配置