《21天学通C++》实现继承(1)

news/2024/11/14 6:12:10/

1.派生语法

语法如下:

class Base{};class Name:access-specifier Base{//access-specifier可以是public、private、protect};

一个简单的继承结构程序:

#include <iostream> 
using namespace std; // 定义一个基类Fish
class Fish {
public:bool isFreshWaterFish; // 一个布尔型成员变量,表示鱼是淡水鱼还是咸水鱼// 一个虚函数Swim,根据鱼的种类输出不同的游泳场所void Swim() {if (isFreshWaterFish) {cout << "swim in lake" << endl; // 如果是淡水鱼,输出在湖中游泳} else {cout << "swim in sea" << endl; // 如果是咸水鱼,输出在海中游泳}}
};// 定义一个派生类Tuna,继承自Fish
class Tuna : public Fish {
public:Tuna() {isFreshWaterFish = false; // 将isFreshWaterFish设置为false,表示Tuna是咸水鱼}
};// 定义另一个派生类Carp,同样继承自Fish
class Carp : public Fish {
public:Carp() {isFreshWaterFish = true; // 将isFreshWaterFish设置为true,表示Carp是淡水鱼}
};int main() {Carp lunch; // 创建一个Carp类型的对象lunchTuna dinner; // 创建一个Tuna类型的对象dinnercout << "lunch: " << endl; // 输出午餐的描述lunch.Swim(); // 调用lunch的Swim函数cout << "dinner: " << endl; // 输出晚餐的描述dinner.Swim(); // 调用dinner的Swim函数system("pause"); return 0;
}

2.访问限定符protected

将属性声明为protected时,允许友元类和派生类访问该属性,但禁止在继承结构之外访问

示例代码如下

class Fish
{
protected://声明为protectedbool isFreshWaterFish;
publicvoid Swim(){if (isFreshWaterFish){cout<<"swim in lake"<<endl;}else{cout<<"swim in sea"<<endl;}        }
};

3.基类初始化

如果基类包含重载的构造函数,可以使用初始化列表传递参数
示例代码如下:

#include <iostream> 
using namespace std; // 定义基类Fish
class Fish {
protected:bool isFreshWaterFish; // 一个受保护的布尔型成员变量,表示鱼是淡水鱼还是咸水鱼Fish(bool isFreshWater) : isFreshWaterFish(isFreshWater) {}// 构造函数,根据传入的参数初始化isFreshWaterFish
public:// 一个虚函数Swim,根据鱼的种类输出不同的游泳场所void Swim() {if (isFreshWaterFish) {cout << "swim in lake" << endl; // 如果是淡水鱼,输出在湖中游泳} else {cout << "swim in sea" << endl; // 如果是咸水鱼,输出在海中游泳}}
};// 定义派生类Tuna,继承自Fish
class Tuna : public Fish {
public:// Tuna的构造函数,使用Fish的构造函数并传入false,表示Tuna是咸水鱼Tuna() : Fish(false) {}
};// 定义另一个派生类Carp,同样继承自Fish
class Carp : public Fish {
public:// Carp的构造函数,使用Fish的构造函数并传入true,表示Carp是淡水鱼Carp() : Fish(true) {}
};int main() {Carp lunch; // 创建一个Carp类型的对象lunchTuna dinner; // 创建一个Tuna类型的对象dinnercout << "lunch: " << endl; // 输出午餐的描述lunch.Swim(); // 调用lunch的Swim函数cout << "dinner: " << endl; // 输出晚餐的描述dinner.Swim(); // 调用dinner的Swim函数system("pause");return 0; 
}

这样可以强迫在构造一个派生类时,必须定义一个这样的函数来为其赋值,避免不定义的情况下,随机数值产生影响

4.在派生类中覆盖基类方法

只要派生类中实现了从基类中继承的函数,且返回值和标值相同,就可以覆盖

class Fish
{
protected:bool isFreshWaterFish;Fish(bool isFreshWater):isFreshWaterFish(isFreshWater){};public:void Swim(){if (isFreshWaterFish){cout<<"swim in lake"<<endl;}else{cout<<"swim in sea"<<endl;}        }
};class Tuna:public Fish{
public:Tuna():Fish(false){};void Swim(){//覆盖基类中的方法cout<<"fu gai"<<endl;}};

5.调用基类中已经被覆盖的方法

使用作用域解析运算符::

Dinner.Fish::Swim();//调用基类中的方法
Dinner.Swim();//调用覆盖后的方法

6.在派生类中的覆盖方法中,调用基类方法

同样使用作用域解析运算符::

class Fish
{
protected:bool isFreshWaterFish;Fish(bool isFreshWater):isFreshWaterFish(isFreshWater){};public:void Swim(){if (isFreshWaterFish){cout<<"swim in lake"<<endl;}else{cout<<"swim in sea"<<endl;}        }
};class Tuna:public Fish{
public:Tuna():Fish(false){};void Swim(){//覆盖基类中的方法cout<<"fu gai"<<endl;Fsih::Swim();//调用基类方法}};

7.派生类中隐藏的基类方法

覆盖是一种极端情况,即派生类中的重载方法会隐藏基类中方法的所有重载版本,导致需要调用时无法调用,示例代码如下

#include <iostream> 
using namespace std;
// 定义基类Fish
class Fish {
public:// 定义一个成员函数Swimvoid Swim() {cout << "Fish swim" << endl;}// 重载Swim函数,带有一个布尔参数isFreshWaterFishvoid Swim(bool isFreshWaterFish) {if (isFreshWaterFish) {cout << "swim in lake" << endl;} else {cout << "swim in sea" << endl;}}
};// 定义派生类Tuna,
class Tuna : public Fish {
public:// 重写基类Fish的Swim成员函数void Swim() {cout << "fu gai" << endl;}
};int main() {Tuna dinner; // 创建Tuna类的对象dinnercout << "dinner: " << endl; dinner.Swim(); // 调用dinner对象的Swim函数,由于Tuna类重写了Swim,所以调用的是Tuna类的Swimdinner.Swim(false); //ERROR,因为派生类中的重载函数Swim(bool isFreshWaterFish)已经被覆盖了system("pause"); return 0; 

若想调用基类中的方法

解决办法1: 使用作用域解析符::

dinner.Fish::Swim(false);

解决方法2: 在派生类中使用using解除隐藏

#include <iostream>
using namespace std;class Fish
{public:void Swim(){cout<<"Fish swim"<<endl;}void Swim(bool isFreshWaterFish){if (isFreshWaterFish){cout<<"swim in lake"<<endl;}else{cout<<"swim in sea"<<endl;}        }
};class Tuna:public Fish{
public:using Fish::Swim;//解除隐藏void Swim(){cout<<"fu gai"<<endl;}};int main(){Tuna dinner;cout<<"dinner: "<<endl;dinner.Swim();dinner.Swim(false);//可以正常调用了system("pause");return 0;}

解决方法3: 在派生类中,把基类中的方法全部重载一次,且在重载方法中就调用基类方法

#include <iostream>
using namespace std;class Fish
{public:void Swim(){cout<<"Fish swim"<<endl;}void Swim(bool isFreshWaterFish){if (isFreshWaterFish){cout<<"swim in lake"<<endl;}else{cout<<"swim in sea"<<endl;}        }
};class Tuna:public Fish{
public://重载基类中的方法Swim()void Swim(){cout<<"fu gai"<<endl;}//重载基类中的重载方法Swim(bool isFreshWaterFish)void Swim(bool isFreshWaterFish){Fish::Swim(isFreshWaterFish);//直接调用基类中的方法}};int main(){Tuna dinner;cout<<"dinner: "<<endl;dinner.Swim();dinner.Swim(false);//可以正常运行了system("pause");return 0;}

http://www.ppmy.cn/news/1443569.html

相关文章

LoggerFactory is not a Logback

错误信息 LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.SimpleLoggerFactory loaded from file:/D:/maven/repository/org/slf4j/slf4j-simple/1.7.26/slf…

Metasploit 溢出 samba 提权漏洞

一、信息收集 1.1 右键单击桌面&#xff0c;选择 Open Terminal Here &#xff0c;打开终端。 1.2 输入命令 nmap -sS -p 139,445 -A 192.168.1.254 ,对目标主机进行扫描,发现 139、445 端口开放。 1.3 输入命令“msfconsole”&#xff0c;启动 MSF 终端。 1.4 输入命令“searc…

webpack 入口和出口的最佳实践

入口和出口的最佳实践 {ignore} 具体情况具体分析 下面是一些经典场景 一个页面一个JS 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 源码结构 |—— src|—— pageA 页面A的代码目录|—— index.js 页面A的启动模块|—— ...|—— pageB 页面…

linux-系统安全与应用

目录 一、账号安全基本措施 1.系统账号清理 2.密码安全控制 3.历史命令安全管理 4.限制su切换用户 二、Linux中的PAM安全认证 1.PAM简介 2.PAM认证原理 3.PAM的配置文件 三、使用sudo提权 四、使用别名进行授权 五、开关机安全控制 1.GRUB限制 2 禁止普通用户登录…

OceanBase开发者大会实录-杨传辉:携手开发者打造一体化数据库

本文来自2024 OceanBase开发者大会&#xff0c;OceanBase CTO 杨传辉的演讲实录—《携手开发者打造一体化数据库》。完整视频回看&#xff0c;请点击这里&#xff1e;> 各位 OceanBase 的开发者&#xff0c;大家上午好&#xff01;今天非常高兴能够在上海与大家再次相聚&…

Springboot自定义注解+aop实现redis自动清除缓存功能

假如我们是一个商家&#xff0c;我们在管理端 设置好菜品之后&#xff0c;每次不同的用户访问我们的菜品&#xff0c;都要查询数据库&#xff0c;当访问者多的时候&#xff0c;会造成数据库的卡顿&#xff0c;所以使用redis进行缓存&#xff0c;这样只需要读取一次数据库&#…

质量管理,怎能不知道SPC?

SPC&#xff08;统计过程控制&#xff09;是质量管理的一个重要组成部分&#xff0c;它可以帮助企业更好地控制生产过程、提高产品质量、降低生产成本、增强企业的竞争力。 SPC是一种应用统计技术对过程中的各个阶段进行评估和监控&#xff0c;建立并保持过程处于可接受的并且稳…

【OceanBase诊断调优】—— OceanBase 数据库日志解读

适用版本&#xff1a;V2.1.x、V2.2.x、V3.1.x、V3.2.x observer.log 日志 OBServer 启动日志 搜索关键字&#xff1a; [NOTICE] 日志说明&#xff1a; OBServer 启动过程中比较关键的日志信息。 [2023-05-11 14:19:09.703272] INFO [SERVER] ob_server.cpp:533 [95303][0]…