c++编程规范------demo2

文章讨论了C++编程中确保对象正确初始化的重要性,包括在构造函数前使用初始化列表初始化成员变量。它提醒开发者注意编译器默认生成的构造函数、拷贝构造函数和析构函数可能带来的问题,特别是在涉及引用和const成员时。此外,文章还提出了显式禁止不需要的编译器生成函数的方法,如使用Uncopyable基类来阻止拷贝和赋值操作。
摘要由CSDN通过智能技术生成

terms 4 :Make sure that objects are initialized before they're used

 确定对象被使用前已经初始化

 定义基本变量类型的同时对其进行赋值操作,创建一个对象时,在构造函数执行前进行初始化,也就是使用初始化列表进行初始化

总是在初始化列表中对所有成员变量赋值

初始化列表的初始化是真正的初始化,在构造函数函数体中对成员变量的赋值是一种伪初始化,初始化列表中的初始化次序最好和成员变量声明的次序相同,另外还要注意,某些变量的初始化次序有先后关系

不同编译单元内定义之non-local static 对象的初始化次序

一个常见的问题是类的包含问题,类A的成员变量中有一个类B的成员对象,类B的成员变量中也有一个类A的成员对象,这样,A的构造完成需要B构造完成,B的构造完成又需要A构造完成,因此会引发很大的错误,另一个问题是,不同的编译单元初始化次序问题,例如使用extern关键词时,被extern修饰的变量所在的编译单元应该首先被初始化,否则当前编译单元的编译就会获得一个未初始化的变量,从而引发错误,解决上述问题可以通过以函数调用替换直接使用对象,这设计到设计模式的知识,笔者理解不深。

terms 5 :  Know what functions C++ silently writes and calls

了解C++默默编写并调用哪些函数

空类

当定义了一个空类,编译器会默认为类声明一个默认(default)构造函数、copy构造函数、默认析构函数、以及一个copy assignment操作符(以上函数均是public且inline的)。

编译器默认生成的函数存在的潜在问题

请看下面的代码实例

在明白下面的实例前,我们应该知道一些C++常识

引用的特点:

  1. 一个变量可取多个别名,也就是说一个变量可以有多个引用。
  2. 引用必须初始化,因此类中的reference成员变量应该像初始化const变量那样使用初始化列表进行初始化。
  3. 引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量。
#include <iostream>

using namespace std;


template<class T>
class NameObject{
public:
    //一个自定义构造函数
    NameObject(string &_name,const T&_year)
        :name(_name),year(_year)   //const成员变量通过初始化列表进行初始化
    {
    }
private:
    string &name;    //reference 引用
    const T year;  // const常量值
};


int main()
{
    string newName("newName");
    string oldName("oldName");
    NameObject<int> name1(newName,23);
    NameObject<int> name2(oldName,16);
//    name1=name2;
    cout << "Hello World!" << endl;
    return 0;
}

上述事例中,由于只自定义了一个构造函数,编译器会默认为我们创建 copy构造函数、默认析构函数、以及一个copy assignment操作符,上述代码中析构函数以及copy构造函数的默认创建没有什么问题,但是由于reference成员变量的存在以及const成员变量的存在,此类的两个对象进行赋值时编译器会发生报错。原因就是引用不可更改,常量值也不能更改。

terms 6 : Explicitly disallow the use of compiler-generated functions you do not want

若不想使用编译器自动生成的函数,就该明确拒绝

紧接着terms5,当我们不希望类使用默认析构函数、以及一个copy assignment操作符时,我们应该明确禁止,那么如何禁止呢,编译器默认生成的函数是public访问属性,我们可以自己将默认析构函数、以及一个copy assignment操作符声明为private,这样,避免了编译器自动生成这些函数,但是这种方法不是绝对安全的,因为member(成员)函数和friend(友元)函数依旧可以访问并使用他们(虽然友元函数在实际的应用中也不推荐),然而我们可以只声明而不定义,这样在使用它们是会出现链接错误,也就是将编译期错误转移到连接期,但是越早发现错误越容易更改和解决错误,此时我们可以设置base class(基类)。

class Uncopyable{
protected:
    Uncopyable(){}    //允许构造和析构
    ~Uncopyable(){}
private:    
    Uncopyable(const Uncopyable&);    //不允许copy 构造和 copy assignment
    Uncopyable& operator =(const Uncopyable&);
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

惜日短

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

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

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

打赏作者

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

抵扣说明:

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

余额充值