你最喜欢的C ++编码风格成语是什么?

你最喜欢的C ++编码风格习语是什么? 我正在问风格或编码排版,比如放置大括号的位置,关键字后面是否有空格,缩进大小等等。这与最佳做法或要求相反,例如总是使用delete[]删除数组。

下面是我最喜欢的一个例子:在C ++类初始化程序中,我们把分隔符放在行的前面,而不是后面。 这可以更容易地保持最新状态。 这也意味着版本之间的源代码控制差异更为清晰。

TextFileProcessor::
TextFileProcessor( class ConstStringFinder& theConstStringFinder ) 

    : TextFileProcessor_Base( theConstStringFinder )

    , m_ThreadHandle  ( NULL )
    , m_startNLSearch (    0 )
    , m_endNLSearch   (    0 )
    , m_LineEndGetIdx (    0 )
    , m_LineEndPutIdx (    0 )
    , m_LineEnds      ( new const void*[ sc_LineEndSize ] )
{
    ;
}

在创建枚举时,将它们放在一个名称空间中,以便可以使用有意义的名称访问它们:

namespace EntityType {
    enum Enum {
        Ground = 0,
        Human,
        Aerial,
        Total
    };
}

void foo(EntityType::Enum entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}

编辑 :但是,这种技术在C ++ 11中已经过时了。 应该使用范围枚举(用enum classenum struct ):它更安全,简洁,更灵活。 使用旧样式的枚举值将被放置在外部作用域中。 使用新式枚举,它们被放置在enum class名称的范围内。
前面的示例使用作用域枚举重写(也称为强类型枚举):

enum class EntityType {
    Ground = 0,
    Human,
    Aerial,
    Total
};

void foo(EntityType entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}

使用范围枚举还有其他显着的好处:缺少隐式转换,可能的前向声明以及使用自定义基础类型(不是默认的int )的能力。


RAII:资源获取是初始化

RAII可能是最重要的成语。 资源应该映射到对象是一种想法,所以根据声明这些对象的范围自动管理它们的生命周期。

例如,如果文件句柄是在堆栈中声明的,那么一旦我们从函数(或循环,或者其中声明的范围)返回,它应该隐式关闭。 如果动态内存分配是作为类的成员进行分配的,那么当该类实例被销毁时,它应该被隐式释放。 等等。 每种资源内存分配,文件句柄,数据库连接,套接字以及任何其他需要获取和释放的资源都应该包装在这样一个RAII类中,它的生命周期取决于它的范围声明。

其中一个主要优点是C ++保证当对象超出范围时调用析构函数,而不管控制权是如何离开该范围的。 即使抛出异常,所有本地对象都将超出范围,因此它们的相关资源将被清除。

void foo() {
  std::fstream file("bar.txt"); // open a file "bar.txt"
  if (rand() % 2) {
    // if this exception is thrown, we leave the function, and so
    // file's destructor is called, which closes the file handle.
    throw std::exception();
  }
  // if the exception is not called, we leave the function normally, and so
  // again, file's destructor is called, which closes the file handle.
}

无论我们如何离开函数,以及打开文件后发生了什么,我们都不需要显式关闭该文件,或者在该函数内处理异常(例如try-finally)。 相反,文件会被清理干净,因为它被绑定到本地对象,当它超出范围时会被销毁。

RAII也很少被称为SBRM(范围绑定资源管理)。

也可以看看:

  • ScopeGuard允许代码“在抛出异常的情况下自动调用”撤销“操作。”

  • 复制交换

    复制交换语言提供了异常安全的复制。 它要求执行正确的拷贝和交换。

    struct String {
      String(String const& other);
    
      String& operator=(String copy) { // passed by value
        copy.swap(*this); // nothrow swap
        return *this; // old resources now in copy, released in its dtor
      }
    
      void swap(String& other) throw() {
        using std::swap; // enable ADL, defaulting to std::swap
        swap(data_members, other.data_members);
      }
    
    private:
      Various data_members;
    };
    void swap(String& a, String& b) { // provide non-member for ADL
      a.swap(b);
    }
    

    您也可以直接使用ADL(参数相关查找)实现交换方法。

    这个成语很重要,因为它处理自我分配[1],做出强有力的例外保证[2],并且通常很容易编写。


    [1]即使自我分配没有尽可能有效地处理,但它应该是罕见的,所以如果它从不发生,这实际上更快。

    [2]如果抛出任何异常,则该对象的状态( *this )不会被修改。

    链接地址: http://www.djcxy.com/p/12667.html

    上一篇: What are your favorite C++ Coding Style idioms

    下一篇: What does it mean "return !! userId"