C++类基础(十七)

news2024/11/18 3:42:13

类的继承——补充知识
● public 与 private 继承(C++ Public, Protected and Private Inheritance)

改变了类所继承的成员的访问权限

//公有继承
struct Base
{
public:
    int x;
private:
    int y;
protected:
    int z;
};
struct Derive : public Base //公有继承基类
{
/*public:
    int x;
protected:
    int z;*/
    void fun()
    {
        x = 10; //可以访问,公有继承基类后,基类中的公有成员在派生类中的访问权限仍然是公有成员
        y = 11; //不可访问,无论哪种继承基类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'
        z = 12; //可以访问,公有继承基类后,基类中的保护成员在派生类中的访问权限仍然是保护成员
    }
};
struct Derive2 : public Derive //公有继承派生类
{
    void fun()
    {
        x = 10; //可以访问,公有继承派生类后,基类中的公有成员在派生类的派生类中的访问权限仍然是公有成员
        y = 11; //不可访问,无论哪种继承派生类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'
        z = 12; //可以访问,公有继承派生类后,基类中的保护成员在派生类的派生类中的访问权限仍然是保护成员
    }
};
int main()
{
    Base val;
    val.x; //类外可以访问该类的公有成员
    val.y; //类外不能访问该类的私有成员, Error: 'y' is a private member of 'Base'
    val.z; //类外不能访问该类的保护成员, Error: 'z' is a protected member of 'Base'

    Derive d;
    d.x; //派生类对象可以在类外访问基类的公有成员
    d.y; //派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'
    d.z; //派生类对象不可在类外访问基类的保护成员,Error: 'z' is a protected member of 'Base'
	
	Derive2 d2;
    d2.x; //派生类的派生类对象可以在类外访问基类的公有成员
    d2.y; //派生类的派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'
    d2.z; //派生类的派生类对象不可在类外访问基类的保护成员,Error: 'z' is a protected member of 'Base'
}
//保护继承
struct Base
{
public:
	int x;
private:
	int y;
protected:
	int z;
};
struct Derive : protected Base //保护继承基类
{
/*protected:
	int x;
protected:
	int z;*/
	void fun()
	{
		x = 10; //可以访问,保护继承基类后,基类中的保护成员在派生类中的访问权限成为保护成员
		y = 11; //不可访问,无论哪种继承基类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'
		z = 12; //可以访问,保护继承基类后,基类中的保护成员在派生类中的访问权限仍然是保护成员
	}
};
struct Derive2 : public Derive //公有继承派生类
{
	void fun()
	{
		x = 10; //可以访问,公有继承派生类后,基类中的公有成员在经过派生类的保护继承后变成保护成员,在派生类的派生类中仍是保护成员
		y = 11; //不可访问,无论哪种继承派生类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'
		z = 12; //可以访问,公有继承派生类后,基类中的保护成员在派生类的派生类中的访问权限仍然是保护成员
	}
};
int main()
{
	Base val;
	val.x; //类外可以访问该类的公有成员
	val.y; //类外不能访问该类的私有成员, Error: 'y' is a private member of 'Base'
	val.z; //类外不能访问该类的保护成员, Error: 'z' is a protected member of 'Base'

	Derive d;
	d.x; //基类中的公有成员在经过派生类的保护继承后变成派生类的保护成员,派生类对象不可在类外访问自己的保护成员,Error: 'x' is a protected member of 'Base'
	d.y; //派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'
	d.z; //保护继承对基类的保护成员的访问权限无影响,派生类对象不可在类外访问基类的保护成员,Error: 'z' is a protected member of 'Base'

	Derive2 d2;
	d2.x; //基类中的公有成员在经过派生类的保护继承后变成派生类的保护成员,派生类的派生类对象不可在类外访问该保护成员,Error: 'x' is a protected member of 'Base'
	d2.y; //派生类的派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'
	d2.z; //保护继承对基类的保护成员的访问权限无影响,派生类的派生类对象不可在类外访问该保护成员,Error: 'z' is a protected member of 'Base'
}
//私有继承
struct Base
{
public:
	int x;
private:
	int y;
protected:
	int z;
};
struct Derive : private Base //私有继承基类
{
/*private:
	int x;
private:
	int z;*/
	void fun()
	{
		x = 10; //可以访问,私有继承基类后,基类中的保护成员在派生类中的访问权限成为私有成员
		y = 11; //不可访问,无论哪种继承基类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'
		z = 12; //可以访问,私有继承基类后,基类中的保护成员在派生类中的访问权限成为私有成员
	}
};
struct Derive2 : public Derive //公有继承派生类
{
	void fun()
	{
		x = 10; //不可访问,公有继承派生类后,基类中的公有成员在经过派生类的私有继承后变成私有成员,在派生类的派生类中已不可见,Error: 'x' is a private member of 'Base'
		y = 11; //不可访问,无论哪种继承派生类,基类的私有成员只能在基类中访问,Error: 'y' is a private member of 'Base'
		z = 12; //不可访问,公有继承派生类后,基类中的保护成员在经过派生类的私有继承后变成私有成员,在派生类的派生类中已不可见,Error: 'z' is a private member of 'Base'
	}
};
int main()
{
	Base val;
	val.x; //类外可以访问该类的公有成员
	val.y; //类外不能访问该类的私有成员, Error: 'y' is a private member of 'Base'
	val.z; //类外不能访问该类的保护成员, Error: 'z' is a protected member of 'Base'

	Derive d;
	d.x; //基类中的公有成员在经过派生类的私有继承后变成派生类的私有成员,派生类对象不可在类外访问自己的私有成员,Error: 'x' is a private member of 'Base'
	d.y; //派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'
	d.z; //基类中的保护成员在经过派生类的私有继承后变成派生类的私有成员,派生类对象不可在类外访问自己的私有成员,Error: 'z' is a private member of 'Base'

	Derive2 d2;
	d2.x; //基类中的公有成员在经过派生类的保继承后变成派生类的私有成员,派生类的派生类对象不可在类外访问该私有成员,Error: 'x' is a private member of 'Base'
	d2.y; //派生类的派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'
	d2.z; //基类中的保护成员在经过派生类的私有继承后变成派生类的私有成员,派生类的派生类对象不可在类外访问该私有成员,Error: 'z' is a private member of 'Base'
}

– public 继承:描述 是一个 的关系 “ ”
– private 继承:描述 根据基类实现出 的关系 “ ”
– protected 继承:几乎不会使用
● using 与继承
– 使用 using 改变基类成员的访问权限
● 派生类可以访问该成员

struct Base
{
public:
    int x = 10;
private:
    int y = 20;
protected:
    int z = 30;
};
struct Derive : Base
{
public:
    using Base::z; //在派生类中使用using改变了基类成员的访问权限,using只能改变在派生类中可见的基类成员的访问权限(即公有成员和保护成员)
    using Base::y; //基类的私有成员在基类外都是不可见的,因此不能使用using改变基类私有成员的访问权限, Error: 'y' is a private member of 'Base'
};
int main()
{
    Derive d;
    std::cout << d.x << '\n'; //Of course OK
    std::cout << d.z << '\n'; //OK
}

● 无法改变构造函数的访问权限

struct Base
{
protected:
    Base(int) {}
};
struct Derive : Base
{
public:
    using Base::Base; //Error: 'Base(int)' is protected within this context
};
struct Base
{
protected:
    void fun()
    {
        std::cout << "void fun()\n";
    }
    void fun(int input)
    {
        std::cout << "void fun(int input): " << input << '\n';
    }
    void fun(char ch)
    {
        std::cout << "void fun(char ch): " << ch << '\n';
    }
};
struct Derive : Base
{
public:
    using Base::fun; //同时改变基类中重载的三个fun()的权限
};
int main()
{
    Derive d;
    d.fun(); //OK
    d.fun(3); //OK
    d.fun('a'); //OK
}

在这里插入图片描述

struct Base
{
protected:
    void fun()
    {
        std::cout << "void Base::fun()\n";
    }
    void go()
    {
        std::cout << "void Base::go()\n";
    }
};
struct Derive : private Base
{
public:
    using Base::fun; //私有继承后,Base::fun()在派生类中成为私有成员,使用using改变其成为公有成员
    void go2()
    {
        std::cout << "void Derive::go2()\n";
        go();
    }
};
int main()
{
    Derive d;
    d.fun();
    d.go2();
}

在这里插入图片描述
– 使用 using 继承基类的构造函数逻辑

struct Base
{
public:
    Base(int) //公有成员
    {
        std::cout << "Base(int)\n";
    }
};
struct Derive : Base
{
public:
    using Base::Base;
};
int main()
{
    Derive d(10);
}

在这里插入图片描述

struct Base
{
public:
    Base(int)
    {
        std::cout << "Base(int)\n";
    }
};
struct Derive : Base
{
public:
    Derive(int x)
        : Base(x) //对基类构造函数的增删改会影响到派生类构造函数的增删改,维护极其不便
    {}
    using Base::Base; //使用using
};

– using 与部分重写

struct Base
{
protected:
    virtual void fun()
    {
        std::cout << "virtual void fun()\n";
    }
    virtual void fun(int)
    {
        std::cout << "virtual void fun(int)\n";
    }
};
struct Derive : Base
{
public:
    using Base::fun;
};
int main()
{
    Derive d;
    d.fun();
    d.fun(100);
}

在这里插入图片描述

struct Base
{
protected:
    virtual void fun()
    {
        std::cout << "virtual void Base::fun()\n";
    }
    virtual void fun(int)
    {
        std::cout << "virtual void Base::fun(int)\n";
    }
};
struct Derive : Base
{
public:
    using Base::fun;
    void fun(int) override
    {
        std::cout << "void Derive::fun(int) override\n";
    }
};
int main()
{
    Derive d;
    d.fun();
    d.fun(100);
}

在这里插入图片描述

struct Base
{
protected:
    Base(int) = default; //保护成员,Error: Only special member functions may be defaulted
};
struct Derive : Base
{
public:
    using Base::Base;
};
int main()
{
    Derive d(10); //Error: Calling a protected constructor of class 'Base'
}
struct Base
{
protected:
    Base() = default; //OK,编译器为Base合成了一个缺省构造函数,权限为public,供外界使用
};
struct Derive : Base
{
};
int main()
{
    Derive d; //OK
}

● 继承与友元:友元关系无法继承,但基类的友元可以访问派生类中基类的相关成员

//基类的友元
struct Base
{
    friend void fun(const Base&); //fun是Base的友元
public:
    int x;
private:
    int y;
protected:
    int z;
};
struct Derive : Base
{
private:
    int xxx;
};
void fun(const Base& b)
{
    b.x; //OK
    b.y; //OK
    b.z; //OK
    const auto& d = static_cast<const Derive&>(b);
    d.xxx; //fun是Base的友元,Derive派生自Base,但fun并不是Derive的友元
}
//派生类的友元
struct Base
{
public:
    int x;
private:
    int y;
protected:
    int z;
};
struct Derive : Base
{
    friend void fun(const Derive&); //fun是Derive的友元
private:
    int xxx;
};
void fun(const Derive& d)
{
    d.x; //fun是Derive的友元,可以访问Derive中所有可见的基类成员
    d.y; //不可访问,Error: 'y' is a private member of 'Base',
    d.z; //fun是Derive的友元,可以访问Derive中所有可见的基类成员
    d.xxx; //fun是Derive的友元,可以访问Derive的所有成员
}

参考
深蓝学院: C++基础与深度解析
C++ Public, Protected and Private Inheritance

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/354356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构与算法】时间复杂度与空间复杂度

目录 一.前言 二.时间复杂度 1.概念 二.大O的渐进表示法 概念&#xff1a; 总结&#xff1a; 三.常见时间复杂度计算举例 例1 例2 例3 例4 例5.计算冒泡排序的时间复杂度 例6.二分算法的时间复杂度 例7.阶乘递归Fac的时间复杂度 例8.斐波那契递归的时间复杂度 …

【MyBatis】| MyBatis的注解式开发

目录 一&#xff1a;MyBatis的注解式开发 1. Insert注解 2. Delete注解 3. Update注解 4. Select注解 5. Results注解 一&#xff1a;MyBatis的注解式开发 MyBatis中也提供了注解式开发⽅式&#xff0c;采⽤注解可以减少Sql映射⽂件的配置。 当然&#xff0c;使⽤注…

推荐几款好用的数据库管理工具

本文主要介绍几款常用的数据库管理软件&#xff08;客户端&#xff09;&#xff0c;包括开源/免费的、商用收费的&#xff0c;其中有一些是专用于 MySQL 数据库的&#xff0c;例如 MySQL Workbench、phpMyAdmin&#xff0c;有一些是支持多种 SQL、NoSQL 数据库的&#xff0c;例…

Kubernetes集群维护—备份恢复与升级

Etcd数据库备份与恢复 需要先安装etcd备份工具yum install etcd -y按不同安装方式执行不同备份与恢复kubeadm部署方式&#xff1a; 备份&#xff1a;ETCDCTL_API3 etcdctl snapshot save snap.db --endpointshttps://127.0.0.1:2379 --cacert/etc/kubernetes/pki/etcd/ca.cr…

知其然更要知其所以然,聊聊SQLite软件架构

SQLite是一个非常受欢迎的数据库&#xff0c;在数据库排行榜中已经进入前十的行列。这主要是因为该数据库非常小巧&#xff0c;而且可以支持Linux、Windows、iOS和Andriod的主流的操作系统。 SQLite非常简单&#xff0c;是一个进程内的动态库数据库。其最大的特点是可以支持不同…

spring的了解以及项目构建

spring理念&#xff1a; 使现有的技术更容易使用&#xff0c;其本身是一个大杂烩&#xff0c;整合了现有的技术框架。 ssh&#xff1a; struct2 spring hibernate ssm &#xff1a;springmvc spring mybatis 优点&#xff1a; spring 是一个免费的开源框架&#xff08;容器…

特征归一化(Normalization)和Batch Normalization的理解

一、理解BN必备的前置知识&#xff08;BN, LN等一系列Normalization方法的动机&#xff09; Feature Scaling&#xff08;特征归一化/Normalization&#xff09;:通俗易懂理解特征归一化对梯度下降算法的重要性 总结一下得出的结论&#xff1a; &#xff08;以下举的例子是针对…

创建基于Vue2.0开发项目的两种方式

前天开始接触基于Vue2.0的前端项目&#xff0c;实际操作中肯定会遇到一些问题&#xff0c;慢慢摸索和总结。   其实&#xff0c;作为开发一般企事业单位应用的小项目&#xff0c;前端的懂一点HTMLCSSJavaScroptJQueryJson&#xff08;或者Xml&#xff09;&#xff0c;后端懂一…

PGLBox全面解决图训练速度、成本、稳定性、复杂算法四大问题!

图神经网络&#xff08;Graph Neural Network&#xff0c;GNN&#xff09;是近年来出现的一种利用深度学习直接对图结构数据进行学习的方法&#xff0c;通过在图中的节点和边上制定聚合的策略&#xff0c;GNN能够学习到图结构数据中节点以及边内在规律和更加深层次的语义特征。…

Dubbo学习笔记2

Dubbo学习笔记&#xff08;二&#xff09; Dubbo常用配置 覆盖策略 规则&#xff1a; 1、精确优先&#xff08;方法级优先&#xff0c;接口次之&#xff0c;全局配置再次之&#xff09; 2、消费者设置优先&#xff08;如果级别一样&#xff0c;则消费方优先&#xff0c;提供…

网络安全-信息收集- 谷歌浏览器插件收集信息,谷歌hacking搜索语法-带你玩不一样的搜索引擎

网络安全-信息收集- 谷歌浏览器插件收集信息&#xff0c;谷歌hacking搜索语法-带你玩不一样的搜索引擎 前言 一&#xff0c;我也是初学者记录的笔记 二&#xff0c;可能有错误的地方&#xff0c;请谨慎 三&#xff0c;欢迎各路大神指教 四&#xff0c;任何文章仅作为学习使用 …

图解LeetCode——剑指 Offer 28. 对称的二叉树

一、题目 请实现一个函数&#xff0c;用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样&#xff0c;那么它是对称的。 二、示例 2.1> 示例 1&#xff1a; 【输入】root [1,2,2,3,4,4,3] 【输出】true 2.2> 示例 2&#xff1a; 【输入】root [1,2,2,nul…

quartz使用及原理解析

quartz简介 ​ Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目&#xff0c;完全由Java开发&#xff0c;可以用来执行定时任务&#xff0c;类似于java.util.Timer。但是相较于Timer&#xff0c; Quartz增加了很多功能&#xff1a; 持久性作业 - 就是保持调度…

瑞典军事研究:从认知心理学的视角探讨军事创新进程

来源&#xff1a;Military Innovation as the Result of Mental Models of Technology 《摘要》 政治紧张局势的加剧和技术发展的进步促使Scandinavian 国家&#xff08;斯堪的纳维亚半岛&#xff0c;欧洲最大的半岛&#xff0c;有挪威、瑞典两国以及芬兰北端的一小部分。&am…

SpringBoot3集成TDengine自适应裂变存储

前言 首先很遗憾的告诉大家&#xff0c;今天这篇分享要关注才可以看了。原因是穷啊&#xff0c;现在基本都是要人民币玩家了&#xff0c;就比如chatGPT、copilot&#xff0c;这些AI虽然都是可以很好的辅助编码&#xff0c;但是都是要钱。入驻CSDN有些年头了&#xff0c;中间有几…

Python没有指针怎么实现链表?

Python没有指针怎么实现链表&#xff1f; 学习数据结构的的链表和树时&#xff0c;会遇到节点&#xff08;node&#xff09;这个词&#xff0c;节点是处理数据结构的链表和树的基础。节点是一种数据元素&#xff0c;包括两个部分&#xff1a;一个是实际需要用到的数据&#xff…

考研复试机试 | C++ | 尽量不要用python,很多学校不支持

目录1.1打印日期 &#xff08;清华大学上机题&#xff09;题目&#xff1a;代码&#xff1a;1.2改一改&#xff1a;上一题反过来问题代码&#xff1a;2.Day of Week &#xff08;上交&&清华机试题&#xff09;题目&#xff1a;代码&#xff1a;3.剩下的树&#xff08;清…

sni第三种模式复现、幽灵猫网络抓包方式复现、所有漏洞复现

sni第三种模式复现 搭建环境 [rootlocalhost nginx]# mkdir certificate [rootlocalhost nginx]# cd certificate/[rootlocalhost certificate]# openssl genrsa -des3 -out ssl.key 4096 [rootlocalhost certificate]# openssl req -new -key ssl.key -out aaa.csr [rootlo…

Django框架之模型视图-URLconf

URLconf 浏览者通过在浏览器的地址栏中输入网址请求网站对于Django开发的网站&#xff0c;由哪一个视图进行处理请求&#xff0c;是由url匹配找到的 配置URLconf 1.settings.py中 指定url配置 ROOT_URLCONF 项目.urls2.项目中urls.py 匹配成功后&#xff0c;包含到应用的urls…

ChatGPT时代,别再折腾孩子了

今天这篇完全是从两件事儿有感而发。昨天在文印店&#xff0c;在复印机上看到装订好的几页纸&#xff0c;我瞥了一眼&#xff0c;是历史知识点&#xff1a;隋朝大运河分为四段&#xff0c;分别是___ ___ ___ ___&#xff0c;连接了五大河___ ___ ___ ___ ______ 年&#xff…