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对象都属于生存期长…

std::function和std::bind

std::function和std::bind std::function 可调用对象 是一个函数指针是一个具有operator()成员函数的类和对象可被转换成函数指针的类对象&#xff1b;一个类成员函数指针&#xff1b; C中可调用对象的虽然都有一个比较统一的操作形式&#xff0c;但是定义方法五花八门&…

如何理解Bounce Rate和Exit Rate

先说说两者的定义&#xff1a; 1&#xff09;Bounce Rate&#xff1a;从某个特定的页面进入网站的Visit中&#xff0c;有多少百分比什么都没有做&#xff08;没有点击任何链接&#xff09;&#xff0c;然后就离开了网站&#xff08;即关闭了这个特定的页面&#xff09;。例如&a…

我的blog开张了,希望大家能多多赏光啊

今天&#xff0c;风很大&#xff0c;前两天刚刚有点春天的感觉&#xff0c;今天全被风刮没了。上网碰到以前很好的同事&#xff0c;谈到如果他也成家了&#xff0c;我们还会不会这样肆无忌惮的说着心事&#xff1f;他说不会的&#xff0c;但是我觉得那是他还没有结婚&#xff0…

配置 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…

【设计模式】五、单例模式(独一无二的对象)

一、概述&#xff1a; 有一些对象我们只需要一个&#xff0c;比方说&#xff1a;线程池&#xff08;threadpool&#xff09;、缓存&#xff08;cache&#xff09;、对话框、处理偏好设置和注册表对象、日志对象、充当打印机、显卡等设备的驱动程序的对象。事实上这些对象只需要…

C++变长参数模板

C变长参数模板 C11 加入了新的表示方法: 允许任意个数、任意类别的模板参数&#xff0c;同时也不需要在定义时将参数的个数固定。 template<typename... Ts> class Magic;模板类 Magic 的对象&#xff0c;能够接受不受限制个数的 typename 作为模板的形式参数&#xff…

数据库设计方法、规范与技巧

本文链接&#xff1a;http://www.openphp.cn/index.php/art.../100/index.html  一、数据库设计过程  数据库技术是信息资源管理最有效的手段。数据库设计是指对于一个给定的应用环境&#xff0c;构造最优的数据库模式&#xff0c;建立数据库及其应用系统&#xff0c;有效存…

C++并行与并发

第 7 章 并行与并发 文章目录第 7 章 并行与并发7.1 并行基础7.2 互斥量与临界区7.3 期物7.4 条件变量7.5 原子操作与内存模型原子操作一致性模型内存顺序总结习题进一步阅读的参考资料7.1 并行基础 std::thread 用于创建一个执行的线程实例&#xff0c;所以它是一切并发编程的…

java 中String ,Date,long 和Timestamp类型的转换

一、String与Date(java.util.Date)的转换 1、String--->Date String str"2014/1/11 12:34:25"; Date datenew Date(); DateFormat sdf new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); //这里规定时间的格式要与String时间类型的格式相同 datesdf.pars…

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;在项目根目录下创建一个…