(P30)继承:不能自动继承的成员函数 ,继承与构造函数 ,友元关系与继承 ,静态成员与继承

本文主要是介绍(P30)继承:不能自动继承的成员函数 ,继承与构造函数 ,友元关系与继承 ,静态成员与继承,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1.不能自动继承的成员函数
    • 2.继承与构造函数
    • 3.友元关系与继承
    • 4.静态成员与继承

1.不能自动继承的成员函数

  • 构造函数
    派生类要定义自己的构造函数,来对派生类成员进行初始化
  • 析构函数
    派生类要定义自己的析构函数,来对派生类成员进行清理工作
  • =运算符

2.继承与构造函数

  • 基类的构造函数不能被继承,派生类中需要声明自己的构造函数

  • 声明构造函数时,只需要对类中新增成员进行初始化,对继承来的基类成员的初始化 (需要调用基类的构造函数来完成)
    只要基类没有默认构造函数,基类的构造函数的调用只能在派生类的构造函数初始化列表中完成。

  • 派生类的构造函数需要给基类的构造函数传递参数

  • 哪几种情况只能在构造函数初始化列表中进行初始化?不能再构造函数体中进行初始化,在体内初始化应该叫做赋值。
    (1)const 成员
    const int n =100;
    (2)引用成员
    int n = 200;
    int &rn = n2;
    (3)基类没有默认构造函数的时候,基类的构造要再派生类构造初始化列表中调用
    (4)类的对象成员没有默认构造函数的时候,只能够再类的构造函数初始化列表中调用该对象的构造函数进行初始化

  • 派生类对象的构造次序:
    先调用基类的对象成员的构造函数,然后调用基类的构造函数,再然后是派生类的对象成员的构造函数,最后是派生类自身的构造函数

  • eg:

#include <iostream>
using namespace std;class Base
{
public:Base(){cout<<"Base..."<<endl;}~Base(){cout<<"~Base..."<<endl;}int b_;
};class Derived : public Base
{
public:Derived(){cout<<"Derived.."<<endl;}~Derived(){cout<<"~Derived.."<<endl;}int d_;};int main(void)
{Derived d;cout<<d.b_<<" "<<d.d_<<endl;return 0;
}
  • 测试:
    要构造派生类对象,先调用基类的构造函数,后调用派生类构造函数
    在这里插入图片描述

  • eg:

#include <iostream>
using namespace std;class Base
{
public:Base(int b) : b_(b){cout<<"Base..."<<endl;}~Base(){cout<<"~Base..."<<endl;}int b_;
};class Derived : public Base
{
public://没有明确指定调用基类的什么构造函数,默认调用基类的默认构造函数Derived(int b, int d) : d_(d), Base(b){cout<<"Derived.."<<endl;}~Derived(){cout<<"~Derived.."<<endl;}int d_;};int main(void)
{Derived d(100,200);cout<<d.b_<<" "<<d.d_<<endl;return 0;
}
  • 测试:
    在这里插入图片描述
  • eg:
#include <iostream>
using namespace std;class ObjectB()
{
public:ObjectB(){cout<<"ObjectB..."<<endl;}~ObjectB(){cout<<"~ObjectB..."<<endl;}
};class ObjectD()
{
public:ObjectD(){cout<<"ObjectD..."<<endl;}~ObjectD(){cout<<"~ObjectD..."<<endl;}
};class Base
{
public:Base(int b) : b_(b){cout<<"Base..."<<endl;}~Base(){cout<<"~Base..."<<endl;}int b_;ObjectB objB_;//若有多个对象成员,构造顺序按照声明的顺序进行构造
};class Derived : public Base
{
public://没有明确指定调用基类的什么构造函数,默认调用基类的默认构造函数Derived(int b, int d) : d_(d), Base(b){cout<<"Derived.."<<endl;}~Derived(){cout<<"~Derived.."<<endl;}int d_;ObjectD objd_;};int main(void)
{Derived d(100,200);cout<<d.b_<<" "<<d.d_<<endl;return 0;
}
  • 测试:
    派生类对象的构造次序:
    先调用基类的对象成员的构造函数,然后调用基类的构造函数,再然后是派生类的对象成员的构造函数,最后是派生类自身的构造函数

在这里插入图片描述

  • eg:P30\01.cpp
#include <iostream>
using namespace std;class ObjectB()
{
public:ObjectB(int objb) : objb_(objb){cout<<"ObjectB..."<<endl;}~ObjectB(){cout<<"~ObjectB..."<<endl;}int objd_;
};class ObjectD()
{
public:ObjectD(int objd) : objd_(obj){cout<<"ObjectD..."<<endl;}~ObjectD(){cout<<"~ObjectD..."<<endl;}int objd_;
};class Base
{
public:Base(int b) : b_(b), objb_(111){cout<<"Base..."<<endl;}//Base的拷贝构造函数//objb_(other.objb_)会调用ObjectB的拷贝构造函数,若没有,则调用默认的拷贝构造函数Base(const Base& other) : objb_(other.objb_), b_(other.b_){}~Base(){cout<<"~Base..."<<endl;}int b_;ObjectB objb_;//若有多个对象成员,构造顺序按照声明的顺序进行构造
};class Derived : public Base
{
public://没有明确指定调用基类的什么构造函数,默认调用基类的默认构造函数Derived(int b, int d) : d_(d), Base(b), objd_(222){cout<<"Derived.."<<endl;}//派生类的拷贝构造函数//Base(other)会调用基类的拷贝构造函数//在构造函数中要完成3件事情:d_(d), Base(b), objd_(222),同样在拷贝构造函数也要完成这三件事情//拷贝构造函数也是一种构造函数,它的写法基本上与构造函数的写法是一样的Derived(const Derived& other) : d_(other.d_), objd_(other.objd), Base(other){}~Derived(){cout<<"~Derived.."<<endl;}int d_;ObjectD objd_;};int main(void)
{Derived d(100,200);cout<<d.b_<<" "<<d.d_<<endl;Base b1(100);Base b2(b1);//会调用拷贝构造函数cout<<b2.b_<<endl;Derived d2(d);return 0;
}
  • 测试:
    在这里插入图片描述

3.友元关系与继承

  • 友元关系不能被继承
    A可以访问B的所有成员(公有、私有、保护成员)
    A是B的友元类,C是A的派生类,那么C不是B的友元类
  • 友元关系是单向的
    A是B的友元类,不带表B是A的友元类
  • 友元关系不能被传递
    A是B的友元类,B是C的友元类,那么A不是C的友元类

4.静态成员与继承

  • 静态成员无所谓继承
    因为静态成员被所有的类共享,其内存只有1份拷贝

  • eg:P30\02.cpp

#include <iostream>
using namespace std;class Base 
{
public:static int b_;
};
int Base::b_ = 100;
class Derived : public Base
{};int main()
{Base b;Base d;cout<<Base::b_<<endl;//推荐使用的方法,因为静态成员无所谓继承,因为它只有1份拷贝//不推荐下面的这种写法cout<<b.b_<<endl;cout<<Derived::b_<<endl;cout<<d.b_<<endl;return 0;
}
  • 测试:
    在这里插入图片描述

这篇关于(P30)继承:不能自动继承的成员函数 ,继承与构造函数 ,友元关系与继承 ,静态成员与继承的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041383

相关文章

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编

Java 继承和多态的作用及好处

《Java继承和多态的作用及好处》文章讲解Java继承与多态的概念、语法及应用,继承通过extends复用父类成员,减少冗余;多态实现方法重写与向上转型,提升灵活性与代码复用性,动态绑定降低圈复杂度... 目录1. 继承1.1 什么是继承1.2 继承的作用和好处1.3 继承的语法1.4 子类访问父类里面的成

python 常见数学公式函数使用详解(最新推荐)

《python常见数学公式函数使用详解(最新推荐)》文章介绍了Python的数学计算工具,涵盖内置函数、math/cmath标准库及numpy/scipy/sympy第三方库,支持从基础算术到复杂数... 目录python 数学公式与函数大全1. 基本数学运算1.1 算术运算1.2 分数与小数2. 数学函数

Java继承映射的三种使用方法示例

《Java继承映射的三种使用方法示例》继承在Java中扮演着重要的角色,它允许我们创建一个类(子类),该类继承另一个类(父类)的所有属性和方法,:本文主要介绍Java继承映射的三种使用方法示例,需... 目录前言一、单表继承(Single Table Inheritance)1-1、原理1-2、使用方法1-

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.