C++ 98/03 应该学习哪些知识16

C++版本发展简史:新特性介绍 阅读详情

RAII 与 pimpl 惯用法

RAII(Resource Acquisition Is Initialization)和pimpl(Pointer to Implementation)是C++中两种常用的惯用法。它们分别用于管理资源和隐藏实现细节。在本篇文章中,我们将介绍RAII和pimpl的原理、应用场景以及如何使用它们来提高代码的质量和可维护性。

RAII(Resource Acquisition Is Initialization)

RAII是一种C++编程惯用法,它用于管理资源(如内存、文件句柄、网络连接等),并确保它们在使用完毕后被正确释放。在RAII中,资源的获取和释放操作被封装在一个类的构造函数和析构函数中,使得资源的生命周期与对象的生命周期一致。

下面,我们以一个简单的例子来说明RAII的用法。假设我们需要在C++程序中打开一个文件,并读取文件中的内容。在传统的C风格编程中,我们需要在代码中显式地调用fopen和fclose函数来打开和关闭文件:

void readFile() {
    FILE* file = fopen("data.txt", "r");
    if (file) {
        // 读取文件内容
        fclose(file);
    }
}

在上述代码中,我们首先调用fopen函数来打开文件,然后检查文件是否成功打开。如果文件打开成功,我们就可以读取文件内容。在读取文件完毕后,我们需要调用fclose函数来关闭文件。然而,这种方式容易出现错误,例如忘记关闭文件、多次关闭同一个文件等等。

使用RAII可以避免这些错误,我们可以使用C++中的智能指针(如std::unique_ptr、std::shared_ptr)来管理文件的生命周期。例如,我们可以定义一个File类来封装文件的操作:

class File {
public:
    File(const std::string& fileName, const std::string& mode) {
        m_file = fopen(fileName.c_str(), mode.c_str());
    }

    ~File() {
        if (m_file) {
            fclose(m_file);
        }
    }

    FILE* Get() const { return m_file; }

private:
    FILE* m_file;
};

在File类中,我们在构造函数中调用fopen函数来打开文件,并在析构函数中调用fclose函数来关闭文件。我们还定义了Get方法来获取文件指针。

然后,在读取文件时,我们可以使用std::unique_ptr来管理File对象的生命周期:

void readFile() {
    std::unique_ptr<File> file(new File("data.txt", "r"));
    if (file->Get()) {
        // 读取文件内容
    }
}

在上述代码中,我们使用std::unique_ptr来创建File对象,并在读取文件完毕后自动释放File对象。由于std::unique_ptr在销毁对象时会自动调用对象的析构函数,因此我们不需要显式地调用fclose函数来关闭文件。

pimpl(Pointer to Implementation)

pimpl是一种C++编程惯用法,它用于隐藏类的实现细节,提高代码的可维护性和可扩展性。在pimpl中,类的实现被封装在一个单独的类中,并通过一个指针来访问该实现类。这样可以避免公开类的私有成员和实现细节,从而保持接口的稳定性,并减少代码的重构成本。

下面,我们以一个简单的例子来说明pimpl的用法。假设我们需要实现一个类来表示二维向量。在传统的C++编程中,我们可以在类的定义中声明向量的x和y坐标:

class Vector2D {
public:
    Vector2D(float x, float y) : m_x(x), m_y(y) {}
    
    float GetX() const { return m_x; }
    float GetY() const { return m_y; }
    
private:
    float m_x;
    float m_y;
};

在上述代码中,我们声明了一个表示向量的x和y坐标的私有成员m_x和m_y。然而,如果我们需要在未来修改类的实现细节,例如更改向量的表示方式或添加更多的成员,我们需要修改类的定义,这可能会导致接口的变化和代码的重构。

使用pimpl可以避免这些问题,我们可以将向量的实现细节封装在一个Vector2DImpl类中,并在Vector2D类中保存一个指向Vector2DImpl的指针:

class Vector2D {
public:
    Vector2D(float x, float y);
    
    float GetX() const;
    float GetY() const;
    
private:
    class Vector2DImpl;
    std::unique_ptr<Vector2DImpl> m_impl;
};

在上述代码中,我们声明了一个名为Vector2DImpl的内部类,并在Vector2D类中保存了一个指向Vector2DImpl的std::unique_ptr。Vector2DImpl类保存向量的实现细节,包括x和y坐标。然后,我们可以在Vector2D的构造函数中创建Vector2DImpl对象,并将其保存在std::unique_ptr中:

class Vector2D::Vector2DImpl {
public:
    Vector2DImpl(float x, float y) : m_x(x), m_y(y) {}
    
    float m_x;
    float m_y;
};

Vector2D::Vector2D(float x, float y) : m_impl(new Vector2DImpl(x, y)) {}

float Vector2D::GetX() const {
    return m_impl->m_x;
}

float Vector2D::GetY() const {
    return m_impl->m_y;
}

在上述代码中,我们定义了Vector2DImpl类,并在Vector2D的构造函数中创建Vector2DImpl对象,并将其保存在std::unique_ptr中。然后,我们可以在GetX和GetY方法中访问Vector2DImpl对象的x和y坐标。

使用pimpl可以使Vector2D类的接口保持稳定,并减少代码的重构成本。如果我们需要更改向量的实现细节,例如将x和y坐标改为极角和极径,我们只需要修改Vector2DImpl类的实现细节,而不需要修改Vector2D类的接口。

下面是一个完整的示例代码,演示了使用pimpl实现向量类的方法:

#include <iostream>
#include <memory>

class Vector2D {
public:
    Vector2D(float x, float y);
    
    float GetX() const;
    float GetY() const;
    
private:
    class Vector2DImpl;
    std::unique_ptr<Vector2DImpl> m_impl;
};

class Vector2D::Vector2DImpl {
public:
    Vector2DImpl(float x, float y) : m_x(x), m_y(y) {}
    
    float m_x;
    float m_y;
};

Vector2D::Vector2D(float x, float y) : m_impl(new Vector2DImpl(x, y)) {}

float Vector2D::GetX() const {
    return m_impl->m_x;
}

float Vector2D::GetY() const {
    return m_impl->m_y;
}

int main() {
    Vector2D v(1.0f, 2.0f);
    std::cout << "X: " << v.GetX() << std::endl;
    std::cout << "Y: " << v.GetY() << std::endl;
    return 0;
}

在上述代码中,我们声明了一个名为Vector2DImpl的内部类,并在Vector2D类中保存了一个指向Vector2DImpl的std::unique_ptr。Vector2DImpl类保存向量的实现细节,包括x和y坐标。然后,我们可以在Vector2D的构造函数中创建Vector2DImpl对象,并将其保存在std::unique_ptr中。最后,我们可以在GetX和GetY方法中访问Vector2DImpl对象的x和y坐标。

总结:

RAII和pimpl是C++编程中非常常用的两个惯用法,它们都可以提高代码的可维护性和可扩展性。RAII主要用于管理资源的生命周期,pimpl主要用于隐藏类的实现细节。在实际的项目中,我们可以结合RAII和pimpl来实现更加健壮和高效的C++代码。

第一篇:C++11关键字 C++11 关键字共73个。 新增关键字: alignas、alignof、char16_t、char32_t、constexpr、decltype、 noexcept、nullptr、static_assert、thread_local。 auto 的意义改变。 register 被视为过时的(可能在未来标准移除)。 export 因为实现支持太少(仅Edison Design Gro 阅读详情

相关推荐

C++98/C++03/C++11/C++14/C++17/C++20 标准帮助文档 2020-09-04

C++98/C++03/C++11/C++14/C++17/C++20 标准帮助文档,更新于 2020 年 9 月 4 日。docsets 格式,可使用 zeal 软件查看

【C++基础编程】#030 C++各代版本以及主要区别

文章目录版本更替1. C++982. C++033. C++114. C++145. 未来版本C++11主要区别 和大家平时用的APP等一样,编程语言每隔一段时间也需要重新制定标准。 C++作为老牌编程语言,有着丰富的STL库以及比较规范的语法,是一个比较受欢迎且适合初学者接触编程时的第一个语言,本文简单介绍一下C++的主要版本更替,以及C++11标准和之前的有何区别。 版本更替 1. C++98 第一版ISO/IEC 14882:1998公开于1998年,通称C++98。 2. C++03 第二版标准IS

杨小浩浩的博客 8251

告别盲打:为NXOpen Python API生成智能代码提示的完整指南

本文提供了一份为NXOpen Python API生成智能代码提示的完整指南。通过配置匹配的Python环境、利用类型存根文件生成工具创建.pyi文件,并在PyCharm或VSCode中正确配置,开发者可以彻底告别“盲打”,获得精准的代码补全和参数提示,从而大幅提升NX二次开发的效率和体验。

weixin_29057695的博客 371

【C/C++】C语言&C++标准版本+不同版本的新特性(C89/90、C95、C99、C11、C17;C++98、C++03、C++11、C++14、C++17、C++20)(截止到2023年)

C语言:C89/90、C95、C99、C11、C17;C++:C++98、C++03、C++11、C++14、C++17、C++20;列出每个版本的一些主要特性。

crr411422的博客 2万+

UE 顶点动画工具 (VAT)

导入模型需要勾选全精度UV。

iesoxj的博客 1643

Flowable前端可视化配置动态审批人:告别硬编码,实现部门领导、项目经理自动分配

本文详细介绍了Flowable前端可视化配置动态审批人的全栈解决方案,通过表达式分配、监听器分配等动态审批人机制,实现从硬编码到智能分配的转变。文章提供了前端扩展bpmn-js设计器、后端动态解析实现方案及性能优化建议,帮助企业应对组织架构变动,提升审批流程的灵活性和效率。

weixin_30352645的博客 473

C++重要版本

这是C++的第二个重大版本,也被称为C++0x。它引入了大量新特性,如自动类型推断(auto关键字)、范围for循环(range-based for loops)、lambda表达式、nullptr和初始化列表等。C++98引入了模板、异常处理、命名空间和新的强大的标准库(包括STL)。C++03主要是对C++98的修订,解决了一些语言和标准库中的缺陷。以上只是C++各版本主要特性的概述,每个版本都包含大量的改进和增强。此外,C++23版本正在开发中,预计将增加更多的特性和改进。

斯坦福-MIT-Harvard-CMU 2256

ArcGIS基础:城市交通网络构建及设施服务分析(一):道路数据处理与拓扑操作

首先需要加载数据, 1:选择这个数据库:,右键导入,选择导入单个要素,弹出“要素类至要素类” 2:输出位置(导入的数据是CAD格式数据)。 3:输出要素类为道路。 4:字段只保留道路类型字段。 这个操作是分类合并各级道路数据。 1:通过属性选择各类道路数据。 2:比如此类都是“干道”。 3:编辑器下来,然后合并即可。 得到如图所示,需要用到三个字段。 上面这个操作是打断道路相交线。 1:选中所有数据。 2:找到高级编辑中的打断相交线。 3:确定即可。 下面进行拓扑检查,虽然我们已经进行合并和打断相交.

yuanYW7556的博客 2万+

语言基础(2):C++标准简介

1、C++98标准 在C++98发布之时,已经具有类及派生类、共有和私有成员的区分、类的构造函数和析构函数、友元、内联函数、赋值运算符的重载,虚函数的概念、函数和运算符的重载、引用、常量(constant),类的保护成员、多重继承、对象的初始化与赋值的递归机制、抽象类、静态成员函数、const成员函数,模板(template)等C++基本特性,并且引入了尴尬的export关键字 ; 更多关于C++...

weixin_30460489的博客 1523

2、稳定性问题全景图——死机、重启、ANR、Crash、黑屏五大类

当 Crash 发生在 system_server、surfaceflinger、mediaserver 等关键系统进程中时,其后果等同于系统级故障,可能触发 Zygote 重启甚至 kernel panic。这类问题在稳定性治理中的优先级应等同于 P0。

woailuojp的博客 49

水很深的深度学习(四): 卷积神经网络CNN

深度学习-CNN,卷积神经网络的概念 上世纪60年代,Hubel等人通过对猫视觉皮层细胞的研究,提出了感受野这个概念,到80年代,Fukushima在感受野概念的基础之上提出了神经认知机的概念,可以看作是卷积神经网络的第一个实现网络,神经认知机将一个视觉模式分解成许多子模式(特征),然后进入分层递阶式相连的特征平面进行处理

专注大数据与人工智能技术分享,欢迎私信加群互相学习! 3624

C++98/03版本知识点汇总

1.类只在代码中出现,不会在运行的程序中出现,即编译时出现;对象在运行的程序中出现,并占用内存,是运行的实体; 2.消息传递的实质是方法的调用; 3.面向对象最突出的特征是:封装性、继承性、多态性 封装:将数据结构和作用在数据结构上的操作组成一个实体,单位是对象,提供动态代码共享; 继承性:提供静态的代码共享; 多态性:不同的对象收到相同的消息产生多种不同的行为方式 编译时的多态性:通

忘世麒麟的专栏 3220

3dmax文件格式转换——.max 转换为 .flt(解决转换后.flt没有纹理贴图的问题)

本文主要介绍如何在3dmax中将.max格式文件转换为.flt格式文件,并解决转换后的文件没有纹理贴图的问题。 在3dmax中,将.max文件转换为.flt格式,只需导出选择.flt格式即可,但是导出的文件在osgEarth中加载后,缺少纹理和贴图。 下面是解决方案: 1、选中加载的模型,然后点击 渲染-> 渲染到纹理 2、将 渲染到纹理 子窗口往下拉,点击 添加 按钮,添加 ...

cchangcs 6175

C++ 98/03 应该学习哪些知识17

内存溢出和内存泄漏

clayhell的博客 1204

YOLOv8改进:全网原创首发 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测 | NeurIPS2022

多尺度卷积注意力(MSCA),有效地提取上下文信息;1)作为注意力MSCA使用;

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 3844

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C/C++超详细的关键字大全!

上表为C++98/03中的63个关键字,红色部分为C语言中的32个关键字。 下边是对每个关键字的详解: 1. asm asm (指令字符串):允许在 C++ 程序中嵌入汇编代码。 2. auto auto(自动,automatic)是存储类型标识符,表明变量"自动"具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。 3. bool bool(布尔)类型,C++ 中的基本数据结构,其值可选为 true(真)或者 false(假)。C++ 中的 bool 类型可以和 int .

清风彬的博客 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

c++63个关键字

C++98/03 关键字 ISO C++98/03关键字共63个,此处严格按标准原文排版: asm do if return typedef auto double inline short typeid boo

1831

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

C++ 关键字详解

1 简介 各个版本的ISOC++都规定以下划线接大写字母或下划线起始的标识符保留给实现,编译器可以用这些保留标识符作为扩展关键字,这不保证可移植性。 C9803关键字 ISO C++98/03关键字共63个,此处严格按标准原文排版: asm do if return typedef auto double inline short typeid bool dynamic_cast int signed typename break else long sizeof union case enum mutab

qq_56187979的博客 692

C++学习笔记之关键字

总结C++关键字 ISO C++98/03关键字共63个,同C语言相同的关键字32个 控制结构关键字(12): 跳转结构:break,continue,goto,return 分支结构:if,else,switch,case,default 循环结构:while,do,for 存储类关键字(6):auto,static,extern, const,volatile, regis

心亮的博客 457

C++ 关键字

C++关键字 关 键字(keyword)是整个语言范围内预先保留的标识符。每个C++关键字都有特殊的含义。经过预处理后,关键字从预处理记号 (preprocessing-token)中区出来,剩下的标识符作为记号(token),用于声明对象、函数、类型、命名空间等。不能声明与关键字同 名的标识符。 各个版本的ISO C++都规定以下划线接大写字母起始的标识符保留给实现。编...

dieleila9149的博客 219

C++11新特性总结(相比C++98)

本文列举一下C++11相比C++98的一些重要变化,做一下知识总结和沉淀。1. C++11 新增_Pragma("once")来保证头文件只会被include一次,用以代...

jameswhale的博客 1226

C++63个关键字

C++98/03 关键字 ISO C++98/03关键字共63个,此处严格按标准原文排版: asm do if return typedef auto double inline short ...

jgm20475的博客 664

【C++】C++11

一文带你由浅入深掌握C++11新特性!

m0_74808907的博客 1500

C++:C++语言的历史发展

C++ 的各个版本,C++17 的下一个版本是 C++20 Year C++ Standard name 1998 ISO/IEC 14882:1998 C++98 2003 ISO/IEC 14882:2003 C++03 2011 ISO/IEC 14882:2011 C++11, C++0x 2014 ISO/IEC 14882:2014 C++14, C++1y...

江南好 1193
上一篇: C++ 98/03 应该学习哪些知识15
下一篇: C++ 98/03 应该学习哪些知识17
五百五。
博客等级 码龄7年 249粉丝 177原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五百五。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值