「C++系列」C++ 修饰符类型

文章目录

  • 一、C++ 修饰符类型
    • 1. 访问修饰符(Access Modifiers)
    • 2. 存储类修饰符(Storage Class Specifiers)
    • 3. 类型修饰符(Type Modifiers)
    • 4. 函数修饰符
  • 二、C++ 修饰符类型-案例
    • 1. 访问修饰符案例
    • 2. 存储类修饰符案例
    • 3. 类型修饰符案例
    • 4. 函数修饰符案例
  • 三、C++ 中的类型限定符
    • 1. `const` 限定符
    • 2. `volatile` 限定符
  • 四、相关链接

在这里插入图片描述

一、C++ 修饰符类型

在C++中,修饰符(Modifiers)用于改变变量、函数、类成员等的默认行为或属性。这些修饰符可以分为几个主要的类别,包括访问修饰符(Access Modifiers)、存储类修饰符(Storage Class Specifiers)、类型修饰符(Type Modifiers)以及函数修饰符(如constnoexcept用于函数)。下面是对这些修饰符类型的一些简要说明:

1. 访问修饰符(Access Modifiers)

访问修饰符控制类成员的访问权限。

  • public:类外部可以访问。
  • protected:只能被其派生类以及该类的成员访问。
  • private:只能被该类内部的成员函数、友元函数以及类本身访问。

2. 存储类修饰符(Storage Class Specifiers)

存储类修饰符决定了变量/函数的存储方式和作用域。

  • auto:自动变量(局部变量),但现代C++中auto关键字有了新的用途,即自动类型推导。
  • register:建议编译器尽可能将变量存储在寄存器中(但现在很多编译器都忽略了这个建议)。
  • static
    • 对于局部变量,static延长了变量的生命周期,但变量的作用域不变。
    • 对于全局变量和函数,static限制了它们的链接性(linkage),使得它们只在定义它们的文件内可见。
    • 对于类成员变量,static使得变量成为所有对象的共享变量。
  • extern:声明变量或函数是在别的文件中定义的,或者是全局的。
  • thread_local(C++11):声明变量的生命周期与线程相同,每个线程都拥有该变量的一个独立实例。

3. 类型修饰符(Type Modifiers)

类型修饰符影响变量或函数的类型或特性。

  • const:表示变量或函数的返回值不可修改。
  • volatile:告诉编译器该变量的值可能会在程序的控制之外被改变(例如,被操作系统、硬件或其他线程改变)。
  • signedunsigned:用于整数类型,指定变量是有符号还是无符号的。
  • longshort:用于整数类型,指定变量的存储大小。
  • enum:定义枚举类型。
  • structclass:定义复合数据类型。

4. 函数修饰符

  • const:用于成员函数,表示该函数不会修改对象的任何成员变量(如果是非静态成员函数)。
  • noexcept(C++11):指定函数不会抛出任何异常。如果函数确实抛出了异常,程序会调用std::terminate()立即终止。
  • virtual:允许在派生类中重写基类的成员函数。
  • override(C++11):明确指定一个成员函数是重写了基类中的虚函数。
  • final(C++11):用于类和方法,防止类被继承或方法被进一步重写。

二、C++ 修饰符类型-案例

当然,下面我将提供几个使用不同C++修饰符的案例代码。这些案例将涵盖访问修饰符、存储类修饰符、类型修饰符以及函数修饰符。

1. 访问修饰符案例

class MyClass {
public:
    void publicFunction() {
        // 公有成员函数,可以在类外部访问
    }

protected:
    void protectedFunction() {
        // 保护成员函数,只能在类内部、派生类以及友元中访问
    }

private:
    void privateFunction() {
        // 私有成员函数,只能在类内部访问
    }
};

2. 存储类修饰符案例

#include <iostream>

class MyClass {
public:
    static int staticVar; // 静态成员变量,所有对象共享
    void printStaticVar() {
        std::cout << staticVar << std::endl;
    }
};

int MyClass::staticVar = 0; // 静态成员变量的定义

int main() {
    MyClass obj1, obj2;
    obj1.staticVar = 10; // 通过任一对象修改
    obj2.printStaticVar(); // 输出 10

    extern int globalVar; // 声明外部变量
    // 假设 globalVar 在其他地方定义并初始化

    // register 修饰符在现代C++中通常不推荐使用,因为它对编译器来说是建议性的
    // register int regVar; // 示例,但通常不推荐这样做

    return 0;
}

// 假设在另一个文件中定义的 globalVar
// int globalVar = 20;

3. 类型修饰符案例

#include <iostream>

class MyClass {
public:
    void display() const { // const 成员函数,保证不修改任何成员变量
        std::cout << "Display function called" << std::endl;
    }

    // 使用 signed 和 unsigned
    void showIntegers() {
        signed int sInt = -10;
        unsigned int uInt = 10;
        std::cout << "Signed: " << sInt << ", Unsigned: " << uInt << std::endl;
    }
};

int main() {
    MyClass obj;
    obj.display();
    obj.showIntegers();
    return 0;
}

4. 函数修饰符案例

#include <iostream>
#include <stdexcept>

class MyClass {
public:
    virtual void virtualFunction() {
        // 虚函数,可以在派生类中被重写
        std::cout << "Base class function" << std::endl;
    }

    void myFunction() noexcept {
        // noexcept 函数,保证不抛出异常
        // 如果尝试抛出异常,程序将调用 std::terminate()
        // 注意:这里的函数体没有实际抛出异常
    }

    void overriddenFunction() override { // 使用 override 明确指定重写
        // 这里是重写基类中的虚函数(假设基类中有相应的虚函数声明)
        std::cout << "Overridden function" << std::endl;
    }

    // 注意:final 修饰符用于类和方法时,表示该类不能被继承或该方法不能在派生类中被重写
    // 这里没有直接展示 final 的用法,因为它需要在类的继承关系中体现
};

// 假设有 MyClass 的派生类,可以展示 virtual 和 override 的用法
// class DerivedClass : public MyClass {
// public:
//     void virtualFunction() override {
//         // 重写 MyClass 中的 virtualFunction
//         std::cout << "Derived class function" << std::endl;
//     }
// };

int main() {
    MyClass obj;
    obj.virtualFunction(); // 调用基类函数
    obj.myFunction(); // 调用 noexcept 函数
    // obj.overriddenFunction(); // 如果 MyClass 中有对应的虚函数声明,则可以这样调用

    // 演示 noexcept 的异常处理(尽管这个例子没有实际抛出异常)
    // try {
    //     throw std::runtime_error("Error");
    //     obj.myFunction(); // 假设 myFunction 内部有抛出异常的代码,但由于 noexcept,这里不会执行
    // } catch (...) {
    //     std::cout << "Exception caught, but myFunction() is noexcept and should not have thrown" << std::endl;
    //     // 注意:如果 myFunction 实际上是 noexcept 的,并且抛出了异常,程序将不会进入这个 catch 块
    //     // 相反,它将调用 std::terminate()
    // }
}

三、C++ 中的类型限定符

在C++中,类型限定符(Type Qualifiers)主要用于限制或改变变量的类型或行为。最常见的类型限定符包括constvolatile。这些限定符可以与基本数据类型、指针、引用等一起使用,以提供额外的信息给编译器和开发者。

1. const 限定符

const限定符用于声明一个变量为常量,意味着一旦该变量被初始化后,其值就不能被改变。const也可以用于修饰函数参数、返回值以及成员函数,以表明这些函数不会(或不应该)修改任何数据。

案例代码

#include <iostream>

void display(const int& value) {
    // 尝试修改value会导致编译错误
    // value = 10; // 编译错误
    std::cout << "Value: " << value << std::endl;
}

int main() {
    const int a = 5; // a是一个常量,其值不能被修改
    // a = 10; // 编译错误

    display(a); // 传递a的引用,但由于是const,所以display函数内部不能修改它

    const int* ptr = &a; // ptr是一个指向常量的指针,不能通过ptr修改a的值
    // *ptr = 10; // 编译错误

    // 但是,ptr本身是可以被修改的,指向另一个常量
    const int b = 20;
    ptr = &b; // 合法,ptr现在指向b

    // 指向常量的指针的常量(即,指针本身也是常量)
    int c = 30;
    const int* const cPtr = &c; // cPtr不能指向其他地址,也不能通过cPtr修改c的值
    // cPtr = &a; // 编译错误,cPtr是常量

    return 0;
}

2. volatile 限定符

volatile限定符告诉编译器该变量的值可能会以编译器无法预见的方式被改变。这通常用于嵌入式编程、多线程编程或访问由硬件直接修改的内存位置时。编译器在优化代码时会考虑变量的volatile属性,以确保每次访问该变量时都直接从其内存地址读取值,而不是使用可能已存储在寄存器中的缓存值。

案例代码:(这个案例可能不那么直观,因为它依赖于外部条件来改变变量的值)

#include <iostream>

// 假设有一个硬件寄存器,其值可能会被外部事件(如中断)改变
volatile int hardwareRegister = 0; // 声明为volatile,因为值可能随时改变

void checkHardwareStatus() {
    // 循环检查hardwareRegister的值,直到它变为非零(表示某种硬件事件)
    while (hardwareRegister == 0) {
        // 在这里,编译器不会优化掉对hardwareRegister的访问
        // 即使它看起来像是在一个无限循环中
    }
    // 处理硬件事件...
    std::cout << "Hardware event detected!" << std::endl;
}

int main() {
    // 在实际应用中,hardwareRegister的值可能由中断服务例程(ISR)改变
    // 这里我们模拟这个行为
    // ...(模拟代码省略)

    checkHardwareStatus();

    return 0;
}

volatile的使用应谨慎,因为它会阻止编译器进行某些优化,这可能会降低程序的性能。只有当确实需要时才应使用volatile

四、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE 面向对象程序设计进阶 IO流 字符输入输出流及底层原理

目录 字符输入流FileReader 空参的read方法 带参的read方法 字符输出流FileWriter 字符输入流底层原理 字符输出流底层原理 字符输入流FileReader 输入流 一次读一个字节 遇到中文时 一次读多个字节 输出流 底层会把数据按照指定的编码方式进行编码 在变成直接写到文件当…

Defensor 4.5:构建数据资产为中心的安全运营体系

5月31日“向星力”未来数据技术峰会上&#xff0c;星环科技重磅发布数据安全管理平台 Defensor 4.5版本。新版本引入了以数据资产为中心的数据安全运营体系&#xff0c;通过智能化大模型技术&#xff0c;帮助企业快速、精准地识别核心重要资产&#xff1b;建设全局的数据安全策…

昇思MindSpore学习笔记6-04计算机视觉--Shufflenet图像分类

摘要&#xff1a; 记录MindSpore AI框架使用ShuffleNet网络对CIFAR-10数据集进行分类的过程、步骤和方法。包括环境准备、下载数据集、数据集加载和预处理、构建模型、模型训练、模型评估、模型测试等。 一、概念 1.ShuffleNet网络 旷视科技提出的CNN模型 应用在移动端 通…

【JavaSE】图书管理系统

目录 最终效果book包Book类BookList类 user包User类AdmiUser类&#xff08;管理员类&#xff09;NormalUser类&#xff08;普通用户类&#xff09; opeeration包IOperation接口FindOpertion类&#xff08;查找操作&#xff09;AddOpertion类&#xff08;增加操作&#xff09;De…

关于解决双屏幕鼠标移动方向问题

1.点开设置》系统》屏幕 2.分清屏幕标识&#xff0c;一般笔记本为1 3.点击要移动的屏幕&#xff0c;然后按住鼠标左键不方进行移动 感谢您的浏览&#xff0c;希望可以帮到您&#xff01;

探索多模态预训练:MAnTiS、ActionCLIP、CPT与CoOp的Prompt技巧

上一篇博文整理了 预训练新范式&#xff08;Prompt-tuning&#xff0c;Prefix-tuning&#xff0c;P-tuning&#xff09; &#xff0c;主要是围绕NLP上的成果&#xff0c;具体的概念本文也不做过多赘述。本篇文章将主要整理几篇有代表性的Prompt方法在多模态领域中的应用。 Mult…

unity使用 MQTT复现plant simulate仿真

unity使用 MQTT复现plant simulate仿真 一、plant simulate端配置 1、plant simulate MQTT组件配置,该组件在类库的信息流类目下,端口不变,填写ip即可; 2、设备配置界面,在控件入口和出口处各挂一个脚本,当物料出入该设备时会分别触发执行这两个脚本,粘贴如下代码; E…

视频怎么压缩变小?最佳视频压缩器

即使在云存储和廉价硬盘空间时代&#xff0c;大视频文件使用起来仍然不方便。无论是存储、发送到电子邮件帐户还是刻录到 DVD&#xff0c;拥有最好的免费压缩软件可以确保您快速缩小文件大小&#xff0c;而不必担心视频质量下降。继续阅读以探索一些顶级最佳 免费视频压缩器选项…

小红书矩阵管理系统:多账号运营的智能解决方案

随着社交媒体的多元化发展&#xff0c;内容创作者和品牌商越来越需要一个能够高效管理多个账号的系统。小红书作为国内领先的生活分享平台&#xff0c;其矩阵管理系统应运而生&#xff0c;为用户带来了多账号发布、批量剪辑视频以及一键分发的便捷功能。本文将详细介绍小红书矩…

必看!微信小程序必备证书!

微信小程序必备SSL证书。在日益增长的数字经济中&#xff0c;微信小程序已成为商家与消费者之间重要的交互平台。由于其便捷性和广泛的用户基础&#xff0c;越来越多的企业选择通过小程序来提供服务。然而&#xff0c;在开发和部署微信小程序时&#xff0c;确保数据安全是一个不…

数据结构笔记之树常考性质6

总结&#xff1a; 具有n个结点的m叉树的最小高度可以通过计算并向下取整得到。高度最小时的情况是所有结点都有m个孩子。

计算机前端面试题总结-暑期实习(答案补充2)

目录 技术方面 二、js 1.js数据类型 1&#xff09;值类型(基本类型) 2&#xff09;引用数据类型&#xff08;对象类型&#xff09; ​编辑 2.判断数据类型是否为数组类型 1&#xff09;Array.isArray() 2&#xff09;instanceof操作符 3&#xff09; Object.prototyp…

飞猪惹怒12306,一张火车票让第三方平台耍尽手段……

小柴已经记不清铁路12306是多少次发出提醒&#xff0c;似乎每一次出行高峰&#xff0c;都会提醒一次。 比如一再强调&#xff0c;购买加速包、付费成为会员就能优先出票&#xff0c;找朋友助力砍一刀&#xff0c;就能获得更高的出票概率……都是假的。‍‍ 因为&#xff0c;铁…

PostgreSQL 中如何处理数据的并发更新冲突解决?

文章目录 一、并发更新冲突的场景二、PostgreSQL 中的并发控制机制&#xff08;一&#xff09; 封锁机制&#xff08;二&#xff09; 事务隔离级别 三、并发更新冲突的解决方法&#xff08;一&#xff09; 重试机制&#xff08;二&#xff09; 使用乐观并发控制&#xff08;三&…

使用机器学习 最近邻算法(Nearest Neighbors)进行点云分析

使用 NearestNeighbors 进行点云分析 在数据分析和机器学习领域&#xff0c;最近邻算法&#xff08;Nearest Neighbors&#xff09;是一种常用的非参数方法。它广泛应用于分类、回归和聚类分析等任务。下面将介绍如何使用 scikit-learn 库中的 NearestNeighbors 类来进行点云数…

打开excel时弹出stdole32.tlb

问题描述 打开excel时弹出stdole32.tlb 如下图&#xff1a; 解决方法 打开 Microsoft Excel 并收到关于 stdole32.tlb 的错误提示时&#xff0c;通常意味着与 Excel 相关的某个组件或类型库可能已损坏或不兼容。 stdole32.tlb 是一个用于存储自动化对象定义的类型库&#x…

【解读大模型(LLM)的token】

文末有福利&#xff01; 当人们谈论大型语言模型的大小时&#xff0c;参数会让我们了解神经网络的结构有多复杂&#xff0c;而token的大小会让我们知道有多少数据用于训练参数。 正像陆奇博士所说的那样&#xff0c;大型语言模型为从文本生成到问题回答的各种任务提供了令人印象…

2024年的设计理念革新:快速获取设计趋势的资源集合!

随着2024年第三季度开始&#xff0c;今年的设计趋势也逐渐出现。与2023 年设计相比&#xff0c;趋势变化空间不大&#xff0c;大部分是在 2023 年度设计趋势的延伸和发展。即使趋势不会一直改变&#xff0c;了解趋势对设计师来说仍然非常重要。接下来&#xff0c;本文将与你分享…

拥抱应用创新,拒绝无谓的模型竞争

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

如何查询并下载韩国签证

登录大韩民国签证门户网站&#xff08;https://www.visa.go.kr&#xff09;&#xff0c;点击“查询/签发”- “办理进度查询及打印”。 2) 输入护照号码、英文姓名及出生日期后点击查询。 3) 若签证通过&#xff0c;办理状态信息栏下面会显示签证信息。 4&#xff09;点击“签证…