【C++】const关键字_运算符重载_继承

目录

Const关键字

常量

常量指针

参数传递

返回值

成员函数

const作用域

运算符重载

继承

继承同名静态成员函数

构造和析构的调用顺序

多重继承

菱形继承(二义性)

虚继承的工作原理

友元

常(成员)函数


Const关键字

        在C++中,const关键字用于指定变量的值在初始化后不能被修改。它主要用于提高代码的安全性和可读性。

常量
const int a = 100;    //常量,初始化后不可修改
常量指针

• `const`在指针前:指针指向的数据是常量,不能被修改。

• `const`在指针后:指针本身是常量,不能指向其他地址。

#include <iostream>  
using namespace std;
int value1 = 100;
int value2 = 2;int main()
{const int* ptr = &value1; //常量指针,const修饰ptr指向的值,可以不用进行初始化int* const ptr1 = &value2;   //指针常量,ptr1初始化后不可指向其他地址,需要进行初始化const int* const ptr3 = &value1; //ptr3指向的地址和值都不可修改return 0;
}
参数传递

• `const`修饰函数参数,可以防止函数内部修改参数的值,这对于引用和指针参数特别有用。

void print(const int& value) {}   // value不能被修改
返回值

• `const`修饰返回值,可以防止返回值被修改。通常用于返回对象时,防止返回的对象被修改。

const string& getName() const {    //防止返回值name被修改return name;
}
成员函数

在成员函数的末尾加上`const`,该成员函数不会修改对象的状态(即不会修改对象的任何成员变量)

class MyClass {
public:int getValue() const {  // const成员函数return value;}
private:int value;
};
const作用域
//跨多个类文件(.cpp)文件使用的时候,定义和引用的地方都要加extern
//a.cpp
extern const int num =1;//b.cpp
extern const int num;//跨头文件(.h)引用时,可通过书写头文件引用
//a.h
const int value =1;//a.cpp
#include"a.h"
int main(){cont<<value;
}

运算符重载

        运算符重载实质上是函数重载(重载+,-,*等函数),也是一种C++静态多态(编译时多态),静态多态是在编译时由编译器确定不会产生额外的开销。

        

#include <iostream>using namespace std;class Box
{
public:int length;  // 成员属性:长int width;   // 成员属性:宽int height;  // 成员属性:高// 默认构造函数,初始化长宽高为1Box(){length = 1;width = 1;height = 1;}// 带参数的构造函数,用于初始化长宽高Box(int length, int width, int height){this->length = length;  // 使用this指针区分成员变量和参数this->width = width;this->height = height;}// 重载加法运算符,用于两个Box对象相加Box operator + (const Box& other){Box temp;  // 创建一个临时Box对象temp.height = this->height + other.height;  // 高度相加temp.width = this->width + other.width;     // 宽度相加temp.length = this->length + other.length;  // 长度相加return temp;  // 返回临时Box对象}// 重载赋值运算符,用于将一个Box对象的值赋给另一个Box对象Box& operator = (const Box& other){this->height = other.height;  // 赋值高度this->width = other.width;    // 赋值宽度this->length = other.length;  // 赋值长度return *this;  // 返回当前对象的引用,支持链式赋值}// 重载累加运算符,用于将一个Box对象的值累加到当前Box对象void operator +=(const Box& other){this->height += other.height;  // 高度累加this->width += other.width;    // 宽度累加this->length += other.length;  // 长度累加}// 重载前++运算符,用于将当前Box对象的长宽高各加1void operator ++ (){cout << "前++" << endl;this->height++;  // 高度加1this->width++;   // 宽度加1this->length++;  // 长度加1}// 重载后++运算符,用于将当前Box对象的长宽高各加1,并返回加1前的值Box operator ++(int)  // 有占位符的是后++{cout << "后++" << endl;Box other = *this;  // 先保存当前对象的值this->height++;  // 高度加1this->width++;   // 宽度加1this->length++;  // 长度加1return other;  // 返回加1前的值}// 重载小于运算符,用于比较两个Box对象的长度bool operator<(const Box& other){return this->length < other.length;  // 比较长度}// 重载等于运算符,用于比较两个Box对象的长度是否相等bool operator == (const Box& other){return this->length == other.length;  // 比较长度}
};// 重载输出流运算符,用于输出Box对象的信息
ostream& operator<<(ostream& out, Box other)
{out << other.height << " " << other.length << " " << other.width << endl;  // 输出高、长、宽return out;  // 返回输出流对象,支持链式输出
}int main()
{Box a, b;  // 创建两个Box对象a和b,默认初始化Box c;     // 创建一个Box对象c,默认初始化c = a + b;  // 调用重载的加法运算符,计算a和b的和,并赋值给ca = b = c;  // 调用重载的赋值运算符,将c的值赋给b,再将b的值赋给aa += b;     // 调用重载的累加运算符,将b的值累加到a++a;        // 调用重载的前++运算符,将a的长宽高各加1cout << "a.height:" << a.height << " a.width:" << a.width << " a.length:" << a.length << endl;  // 输出a的长宽高a++;        // 调用重载的后++运算符,将a的长宽高各加1cout << "a.height:" << a.height << " a.width:" << a.width << " a.length:" << a.length << endl;  // 输出a的长宽高cout << a << b << c << endl;  // 调用重载的输出流运算符,输出a、b、c的信息return 0;
}

继承

继承同名静态成员函数
class father
{
public:static void fun(){cout << "father's fun" << endl;}
};
class son :public father
{
public:static void fun(){cout << "son's fun" << endl;}
};
int main()
{son::fun();//输出"son's fun"son::father::fun();//输出"father's fun"return 0;
}
构造和析构的调用顺序
  • 构造函数:派生类(子类)的构造函数会首先调用基类的构造函数来初始化基类(父类)部分,然后初始化派生类部分。如果基类有默认构造函数,可以不显式调用。
  • 析构函数:析构函数的调用顺序与构造函数相反,先调用派生类的析构函数,再调用基类的析构函数
#include <iostream>using namespace std;class father
{
public:int temp;father(int a){cout << "父类构造1" << endl;}father(int a, int b){cout << "父类构造2" << endl;}void fun(){cout << "father fun" << endl;}~father(){cout << "父类析构" << endl;}
};
class son :public father
{
public:son() :father(2, 4)//父类没有无参构造,子类声明父类走的哪个构造{cout << "子类构造" << endl;}~son(){cout << "子类析构" << endl;}
};
int main()
{son s;return 0;
}
多重继承

        C++支持多重继承,子类可同时继承多个父类

class B  {};class C  {};class D : public B, public C {};
菱形继承(二义性)

 

        菱形继承会产生二义性问题(D中继承的变量a,不知道是来自类B还是类C),可以通过虚继承利用作用域来解决二义性

虚继承的工作原理
  • 共享基类实例:通过虚继承,类B和类C共享同一个类A的实例,而不是各自拥有一个独立的实例。
  • 构造函数调用:当创建类D的对象时,类A的构造函数只会被调用一次。这是通过在类D的构造函数中显式调用类A的构造函数来实现的。如果类D的构造函数中没有显式调用类A的构造函数,则会调用类A的默认构造函数(如果存在).
  • 访问路径:由于类A的实例是共享的,类D可以通过类B或类C访问类A的成员,但访问路径是唯一的,因为类A的实例只有一个.

友元

        友元可以让一个类访问另一个类私有成员,使用友元函数/类 的优缺点:

优点:提高函数效率,表达清晰简单

缺点:破坏类的封装机制,尽量不使用

class A
{
private:int temp=1;friend void fun();//声明函数fun为类A的友元函数friend class B;//声明类B为类A的友元函数,在类B中可以访问类A的私有成员变量
};
void fun()
{A a;cout <<"a.temp: "<< a.temp << endl;
}
class B
{
public:void Api(){A a;cout << "a.temp: " << a.temp << endl;}
};
int main()
{fun();B b;b.Api();return 0;
}
常(成员)函数
  • 定义:常函数使 调用类的成员函数不会对类做任何修改
  • 格式:返回值 函数名(参数)const {函数体}
  • 特点:
    • 可读不可写数据成员,也就是无法修改
    • 常函数的this指针式const Class *型
    • 常成员函数只能调用常成员函数,不能更改类中的成员状态(与const相似)
    • 常函数能修改传入自身的形参以及内部定义的局部变量
    • 常对象只能调用常函数,不能调用普通函数。
#include <iostream>using namespace std;class Student
{
public:Student() {}Student(const string& nm, int sc = 0) :name(nm), score(sc) {}void set_student(const string& nm, int sc = 0){name = nm;score = sc;}const string& get_name()const;//常函数int get_score() const{return score;}
private:string name;int score;
};
const string& Student::get_name()const
{//set_student();//常函数只能调用常函数,不能调用类中未使用const修饰的成员函数。get_score();return name;
}
void output_student(const Student& student)
{cout << "student.get_score(): " << student.get_score() << endl;
}
int main()
{Student stu("wang",85);output_student(stu);
}

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

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

相关文章

Java(day4)

二维数组 静态初始化 动态初始化 练习 public class test1 {public static void main(String[]args){int arr[][]{{22,66,44},{77,33,88},{25,45,65},{11,66,99}};int sum0;for(int i0;i<arr.length;i){int a0;for(int j0;j<arr[i].length;j){sumarr[i][j];aarr[i][j];…

「Mac畅玩鸿蒙与硬件52」UI互动应用篇29 - 模拟火车票查询系统

本篇教程将实现一个模拟火车票查询系统&#xff0c;通过输入条件筛选车次信息&#xff0c;并展示动态筛选结果&#xff0c;学习事件处理、状态管理和界面展示的综合开发技巧。 关键词 条件筛选动态数据展示状态管理UI交互查询系统 一、功能说明 模拟火车票查询系统包含以下功…

Cherno C++学习笔记 P50 C++当中的动态库

在上一篇文章当中我们学习了C当中是如何使用静态库的&#xff0c;这一篇我们会讲一下如何使用动态库&#xff0c;并同样用GLFW这个已有的库来举例子。 有了静态库的经验&#xff0c;其实动态库就好理解和使用多了。这两者的区别是&#xff0c;静态链接发生在编译的时候&#x…

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度 一&#xff0c; PWM实现原理二&#xff0c;软件实现三&#xff0c;正点原子裸机开发总结 一&#xff0c; PWM实现原理 PWM和学习51时候基本上一致&#xff0c;控制频率&#xff08;周期&#xff09;和占空比&#xff0c;51实验…

1.Python浅过(语法基础)

1.简介 Python是一种面向对象的解释型高级编程语言&#xff0c;是强类型的动态脚本语言。 解释型语言跨平台性比编译型语言&#xff08;如c语言&#xff09;好。 print("hello world")2.Bug,Debug 多看&#xff0c;多思考&#xff0c;多尝试、查资料、记录 3.prin…

Flutter:邀请海报,Widget转图片,保存相册

记录下&#xff0c;把页面红色区域内的内容&#xff0c;转成图片后保存到相册的功能 依赖 # 生成二维码 qr_flutter: ^4.1.0 # 保存图片 image_gallery_saver_plus: ^3.0.5view import package:demo/common/index.dart; import package:ducafe_ui_core/ducafe_ui_core.dart; i…

JVM实战—12.OOM的定位和解决

大纲 1.如何对系统的OOM异常进行监控和报警 2.如何在JVM内存溢出时自动dump内存快照 3.Metaspace区域内存溢出时应如何解决(OutOfMemoryError: Metaspace) 4.JVM栈内存溢出时应如何解决(StackOverflowError) 5.JVM堆内存溢出时应该如何解决(OutOfMemoryError: Java heap s…

科研绘图系列:R语言单细胞数据常见的可视化图形

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理图1图2图3图4图5图6系统信息参考介绍 单细胞数据常见的可视化图形 因为本教程是单细胞数据,因此运行本画图脚本需要电脑的内存最少32Gb 加载…

公共数据授权运营机制建设(六大机制、存在问题、发展路径)

前言在国家战略部署下&#xff0c;学界和各地方政府从理论和实践两个层面积极探索公共数据授权运营机制。本期将从学理上剖析公共数据授权运营的基本内容&#xff0c;说明公共数据授权运营到底包括哪些内容&#xff0c;并且举例说明各地在公共数据授权运营机制建设方面的典型经…

CDP集成Hudi实战-spark shell

[〇]关于本文 本文主要解释spark shell操作Hudi表的案例 软件版本Hudi1.0.0Hadoop Version3.1.1.7.3.1.0-197Hive Version3.1.3000.7.3.1.0-197Spark Version3.4.1.7.3.1.0-197CDP7.3.1 [一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do s…

Python爬虫基础——百度新闻页面结构剖析

经过上一篇文章文章[Python爬虫基础——认识网页结构(各种标签的使用)]的介绍&#xff0c;我们对网页结构已经有了初步的认识&#xff0c;本篇文章针对百度新闻界界面结构进行剖析。 在浏览器地址栏中输入https://news.baidu.com/&#xff0c;然后按住F12打开发这工具在“Eleme…

【老白学 Java】保存 / 恢复对象状态

保存、恢复对象状态 文章来源&#xff1a;《Head First Java》修炼感悟。 上两篇文章分别讨论了对象序列化和反序列化&#xff0c;主要是针对数据文件进行读、写操作的介绍。 本篇文章通过一个完整的例子&#xff0c;复习一下对象保存与恢复的操作步骤&#xff0c;在文章最后做…

进程间通信——网络通信——UDP

进程间通信&#xff08;分类&#xff09;&#xff1a;网络通信、无名管道、有名管道、信号、消息队列、共享内存、信号量集 OSI七层模型&#xff1a;&#xff08;理论模型&#xff09; 应用层 : 要传输的数据信息&#xff0c;如文件传输&#xff0c;电子邮件等 表示层 : 数…

3272 小蓝的漆房

将devc设置支持编译就能用新的遍历方式 for(auto &x : s)//遍历容器s&#xff0c;变量为x /* 多循环的嵌套&#xff1a; 计数是否需要重置为0; 是否因为ans定义成全局变量导致ans在比较多时候会出现错误*/ /* 1.对于一个标准色&#xff0c;对目标数组遍历&#xff0c; 如…

海外云服务器能用来做什么?

海外云服务器不仅服务种类繁多&#xff0c;而且能满足多行业的需求&#xff0c;方便了越来越多的企业与个人。本文将探讨海外云服务器的核心服务及其适用领域&#xff0c;帮助企业更好地了解这一技术资源。 云存储&#xff1a;安全高效的数据管理 海外云服务器为用户提供了稳定…

导出中心设计

业务背景 应用业务经常需要导出数据&#xff0c;但是并发的导出以及不合理的导出参数常常导致应用服务的内存溢出、其他依赖应用的崩溃、导出失败&#xff1b;因此才有导出中心的设计 设计思想 将导出应用所需的内存转移至导出中心&#xff0c;将导出的条数加以限制&#xf…

Re77 读论文:LoRA: Low-Rank Adaptation of Large Language Models

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;LoRA: Low-Rank Adaptation of Large Language Models ArXiv网址&#xff1a;https://arxiv.org/abs/2106.09685 官方GitHub网站&#xff08;包含在RoBERTa、DeBERTa、GPT-2上用Lora微调…

Redis 数据库源码分析

Redis 数据库源码分析 我们都知道Redis是一个 <key,value> 的键值数据库&#xff0c;其实也就是一个 Map。如果让我来实现这样一个 Map&#xff0c;我肯定是用数组&#xff0c;当一个 key 来的时候&#xff0c;首先进行 hash 运算&#xff0c;接着对数据的 length 取余&…

我的nvim的init.lua配置

nvim的配置文件路径在&#xff5e;/.config/nvim路径下&#xff1a; 一、目录如下&#xff1a; coc-settings.json文件是配置代码片段路径的文件init.lua配置文件的启动脚本lua/config.lua 全局配置文件lua/keymaps.lua 快捷键映射键文件lua/plugins.lua 插件的安装和配置文件…

权限掩码umask

1 、 设置新建文件或目录的默认权限 在 Linux 系统中&#xff0c;当用户创建一个新的文件或目录时&#xff0c;系统都会为新建的文件或目录分配默认的权限&#xff0c;该默认权限与umask 值有关&#xff0c;其具体关系是&#xff1a; 新建文件的默认权限 0666-umask 值 新建…