C++17代码整洁之道

C++17代码整洁之道

C++代码整洁的基本规范

良好的命名

  • 名称应该自解释
  • 使用域中的名称
  • 避免使用匈牙利命名法(即名称前加类型)
  • 不要通过注释禁用代码

函数

  • 只做一件事情

    • 函数体量要小

    • 当你为函数找到一个富有表现力的名称时,名称中没有连词

    • 圈复杂度低

    • 函数的参数要少

  • 函数尽可能小

    函数应该很小,45行,做多1215行,不能再多了

  • 使用容易理解的函数名

    std::string head = html.substr(...);
    

    引入一个有意图的名称,将更加容易理解

    std::string extractHtmlHeader(const std::string& html)
    {retrun html.substr();
    }
    
  • 函数的参数和返回值

    • 函数的参数越少越好

    • 函数中最好不要有标志参数bool

      使用bool类型说明你很有可能需要在函数中做判断,那为什么不分别用两个函数处理两种情况呢

    • 避免使用输出参数,如果要返回多个参数请使用std::tuple

    • 不要传递或者返回NULLnullptr

      原因:

      1. 导致很多空检查,增加代码复杂性
      2. 对象所有权问题
    • 首先在栈上构造对象而不是在堆上

      在堆上创建对象给创建者增加了管理资源的责任,而原来所担心的昂贵的拷贝构造成本也不需要担心了,因为C++11增加了std::move()移动语义,即允许资源从一个对象"移动"到另一个对象

    • 在函数的参数列表中用**const引用代替指针**

    • 如果一定要使用指针,请使用智能指针

    • 尽量使用`const

  • 用C++类型转换代替C风格类型转换

    C风格:

    float x{3.12};
    int i = int(x);
    

    缺陷:不会在编译期进行类型检查可能产生错误

    C++风格

    int i = static_cast<int>(x);
    

    优点:在编译期进行类型检查

现代C++的高级概念

资源管理

  • 资源申请即初始化

    构造时获得,析构时释放

    class Res final
    {
    public:Res() { sourse = new T(); }~Res() { delete sourse; }
    private:T* sourse;
    };
    
  • 智能指针

    1. 具有独占所有权的std::unique_ptr<T>

      一个对象只能由一个std::unique_ptr<T>占有

      class person
      {
      public:
      private:int age;
      };
      std::unique_ptr<person> p1{ std::make_unique<person>() };
      //类型推导更加的简洁
      auto p2{ std::make_unique<person>() };
      

      不允许调用std::unique<T>拷贝构造函数,但可以使用std::move将所持有的资源移动给另一个std::unique<T>,将在后续部分进行讲解

    2. 具有共享所有权的std::shared_ptr<T>

      std::shared_ptr<T>可以与其他std::shared_ptr<T>实例共享资源的所有权

      std::shared_ptr<T>提供简单且有限的垃圾回收功能,内部存在一个引用计数器

      image-20210522100445846
      std::shared_ptr<person> s1 = std::make_shared<person>();
      std::shared_ptr<person> s2;
      s2 = std::move(s1);
      

      上面例子并没有修改智能指针计数,但在移动之后必须要小心使用s1,因为他可能是空的**(持有nullptr)**

      3.无所有权但是能安全访问的std::weak_ptr<T>

      ​ 他对资源的生命周期没有影响std::weak_ptr<T>仅仅观察他所指向的资源

  • 避免显式的newdelete

    new和delete会增加代码的复杂度: 当不可避免的使用new和delete时,你必须处理异常情形

    显式的调用new和delete可以通过以下措施避免

    • 尽可能使用栈内存,栈内存永远不会泄露
    • make function分配内存
    • 尽量使用容器
  • 管理特有资源

Move语义

什么是move语义呢?在许多情况下,旧的C++强迫我们使用复制构造函数,实际上我们并不想要对象的深拷贝,相反,我们只移动对象的负载就可以使用std::move

  • 左值与右值的关系

    左值右值是历史术语(这个翻译的属实垃圾)

    左值更好的解释是:一个locator value,一个在内存有位置的对象

    相对于左值,右值是一个不是左值的对象,右值是一个临时对象或者是子对象

    字面值 42 是一个右值。在内存中没有可标识的位置,所以不能为他赋值,当然,右值也可以占用栈上的数据区内存,但是这个内存是临时分配的,而且复制完成后就会马上释放

  • 右值引用

    右值引用使优定位右值的内存成为可能,并且可以修改

    int&& temp = 12 + 34;
    int* p1 = &temp;
    *p1 = 999;
    
  • 少用std::move()

    编译器自己会优化,自己少用

  • 零原则

1621662448137

**缺陷:**违反了五大原则copy/move构造器以及copy/move赋值运算符都没有显示定义

int main()
{Mystring astring("test",4);Mystring anotherstring{astring};return 0;
}

在这个实例中,我们拷贝的对象是存储字符串的地址指针,而不是内存中指针指向的对象。

这就意味着,自动调用默认的复制构造函数后,两个对象指向同一个内存,如果对象析构,将会导致双重删除,会造成严重的后果。

**零原则:**在你实现类的时候,应该不需要声明或定义析构函数,拷贝构造赋值函数,移动构造赋值函数。用C++智能指针来管理资源

面向对象

类的设计原则

我太菜,以后理解到了再写

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

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

相关文章

使用.NET Remoting开发分布式应用——基于租约的生存期(转载)

使用.NET Remoting开发分布式应用——基于租约的生存期一&#xff0e;概述知名类型的SingleCall对象可以在客户程序的方法调用之后被垃圾收集器清理掉&#xff0c;因为它没有保持状态&#xff0c;属于无状态的。而客户激活的类型的对象和知名类型的SingleTon对象都属于生存期长…

配置 Sybase数据源

1.Start-- > All Programs -- > Sybase - -> Connectivity --> click ‘Open Client Directory Service Editor’ 2.在Server窗口右击鼠标 Right Click -- > select ‘Add’ item 3 弹出’Input Server Name’窗口,输入Server name(服务器名称) ServerName: DM…

C++虚函数表

虚函数 对C 了解的人都应该知道虚函数&#xff08;Virtual Function&#xff09;是通过一张虚函数表&#xff08;Virtual Table&#xff09;来实现的。简称为V-Table。在这个表中&#xff0c;主是要一个类的虚函数的地址表&#xff0c;这张表解决了继承、覆盖的问题&#xff0…

Proxy Pattern using C# (转载)

Proxy Pattern&#xff08;代理模式&#xff09;属于Structural Pattern&#xff08;结构型模式&#xff09;&#xff0c;Proxy Pattern-为Client真正要调用的对象提供一个代理&#xff08;Surrogate or placeholder&#xff09;&#xff0c;来控制Client对该对象的访问。 1. U…

BlackBerry 应用程序开发者指南 第一卷:基础--第5章 支持的媒体内容(Media Content)...

作者:Confach 发表于April 23,2006 15:02 pm版权信息:可以任意转载, 转载时请务必以超链接形式标明文章原始出处 和作者信息.http://www.cnblogs.com/confach/articles/387902.html5第5章 支持的媒体内容&#xff08;Media Content&#xff09;PME内容 播放媒体内容 监听媒体内…

Qt 入门 ---- 如何在程序窗口显示图片?

步骤&#xff1a; 1. 选择资源&#xff08;准备图片&#xff09; 2. 加载资源&#xff08;导入图片&#xff09; 3. 使用资源&#xff08;显示图片&#xff09; 具体操作流程&#xff1a; ① 从网上寻找合适的图片素材&#xff0c;下载到本地&#xff0c;在项目根目录下创建一个…

Enterprise Library 2.0 技巧(3):记录ASP.NET站点中未处理的异常

这篇文章不能算是Enterprise Library 2.0的一个技巧&#xff0c;只是Logging Application Block的一个简单应用而已&#xff0c;在这里我们使用Logging Application Block来记录一个ASP.NET 2.0站点中未处理的异常到数据库中&#xff0c;当然你也可以记录到文本文件中&#xff…

C++自定义对象如何支持Range-based循环语法

自定义对象如何支持Range-based循环语法 至少实现以下两种语法: //返回第一个迭代子的位置 Iterator begin() //返回最后一个迭代子的下一个位置 Iterator end()迭代子需要支持如下三种方法: operator(自增)operator! (判不等)operator* (解引用) #include <iostream>…

SharePoint 2013 本地开发解决方案以及程调试

SharePoint 2013 本地开发解决方案以及程调试 在SharePoint开发中&#xff0c;我们需要在部署有SharePoint环境的服务器中开发&#xff0c;这是一件让人很苦恼的事情&#xff0c;毕竟不能一个项目多人开发配备多台服务器&#xff0c;这就需要本地开发。 本来自己以为SharePoint…

Linux与C++11多线程编程(学习笔记)

多线程编程与资源同步 在Windows下,主线程退出后,子线程也会被关闭; 在Linux下,主线程退出后,系统不会关闭子线程,这样就产生了僵尸进程 3.2.1创建线程 Linux 线程的创建 #include <unistd.h> #include <stdio.h> #include <pthread.h> void* threadfunc(…