Effective C++笔记简易总结以及程序演示

简介: 4、确定对象被使用前已被初始化在使用变量时不进行初始化是不好的行为,在程序中有可能读入一个未初始化的值就可能导致程序崩溃。

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

在使用变量时不进行初始化是不好的行为,在程序中有可能读入一个未初始化的值就可能导致程序崩溃。

对于内置类型,保证在使用对象之前进行初始化:

int x = 0;
const char* text = "A C-style string"

double d;
std::cin >> d;

对于结构体成员的初始化,要区别初始化和赋值的区别:

class PhoneNumber
{
private:
    int name;
    int number;
public:
    PhoneNumber(){name = 0;number = 0;} //这里是赋值不是初始化
    PhoneNumber():name(0),number(0){} //这里才是初始化(成员初值列)
};

在C++中,对象的成员变量的初始化动作发生在进入构造函数本体之前,上面利用成员初值列的方法初始化的效率较高,同时不浪费default构造函数做的一切

另外一种情况,C++对“定义于不同编译单元内的non-local static对象”的初始化相对次序并无明确定义。也就是如果某编译单元内的某个non-loacl static对象的初始化动作使用了另一个编译单元内某个non-local static对象,而它所用到的这个对象可能尚未被初始化,如果出现这种情况,那么问题是致命的。

解决这个的方法就是将每个non-loacl static对象搬到自己的专属函数内(该对象在此函数内被声明为static)。这些函数返回一个reference指向它所含的对象。然后用户调用这些函数,而不直接指涉这些对象。这个手法的基础在于:C++保证,函数内的local static对象“会在该函数被调用期间”、“首次遇上该对象之定义式”时被初始化:

class FileSystem{...};
FileSystem& tfs()           //这个函数用来替换tfs对象;它在FileSystem class            
{                  //中可能是个static。定义并初始化一个local static对象,                  
    static FileSystem fs;   //返回一个reference指向上述对象。
    return fs;
}
class Directory{...};
Directory::Directory(params)
{
    ...
    std::size_t disks = tfs().numDisks(); //调用对象
    ...
}
Directory& temDir()  //定义temDir对象为“函数对象”
{
    static Directory td;
    return td;
}

如此,在调用temDir对象时,C++会对tfs进行初始化,并对temDir也进行初始化

5、了解并拒接默默调用的函数

空类并不是空类,C++编译器会自动为其声明一个copy构造函数、一个copy assignment操作符和一个析构函数,如果你没有声明任何构造函数,那么编译器也会为你声明一个default构造函数(这些函数都是public且inline的)。

这些会引起一些比较容易忽视的问题:比如通过copy assignment操作符去给一个类赋值一个拥有不能进行赋值成员的类时会引起编译器的警告(类中有引用成员,将这个类用过=号赋予给另一个类时会出现错误,因为C++不允许reference改变指向对象)

解决这个“麻烦”的方法,即不想使用编译器自动生成的函数。手动声明copy构造函数和copy assignment操作符,将其为private:

class Uncopyable
{
protected:
    Uncopyable(){}
    ~Uncopyable(){}
private:
    Uncopyable(const Uncopyable&);
    Uncopyable& operator=(const Uncopyable&);
};

class HomeForSale:private Uncopyable{
    ...
};

这样,任何想尝试拷贝HomeForSale对象的行为编译器会进行报错。

6、别让异常逃离析构函数

析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉异常,然后吞下他们(不传播)或者结束程序;
如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。

22、将成员变量名声明为private

class AccessLevels
{
public:
    int getReadOnly() const {return readOnly;}
    void setReadWrite(int value) {readWrite = value;}
    int getReadWrite() const { return readWrite;}
    void setWriteOnly(int value) {writeOnly = value;}

private:
    int noAccess; //对此int无任何访问
    int readOnly; //对此int做只读访问
    int readWrite; //对此int做读写访问
    int writeOnly; //对此int做只能写访问
};

写成上述这样是值得建议和安全的,有以下好处:
1、完美的封装性,不管你的成员变量以后怎么变使用者都不会知道;
2、可以为“所有可能的实现”提供弹性。
类中所有的成员变量都应该为private,不管是public还是protected都是不安全的,因为一个可以被所有人访问,另一个可以被所有“亲戚”访问,protected相比较public并不具有多好的隐秘性。

目录
相关文章
|
29天前
|
C++
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
32 0
|
2天前
|
C++
【C++基础】程序流程结构详解
这篇文章详细介绍了C++中程序流程的三种基本结构:顺序结构、选择结构和循环结构,包括if语句、三目运算符、switch语句、while循环、do…while循环、for循环以及跳转语句break、continue和goto的使用和示例。
10 2
|
1月前
|
C++ 容器
【C/C++笔记】迭代器
【C/C++笔记】迭代器
16 1
|
29天前
|
PHP C++ Python
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
23 0
|
1月前
|
存储 安全 程序员
【C/C++笔记】迭代器范围
【C/C++笔记】迭代器范围
54 0
|
1月前
|
C++
c++学习笔记03 程序流程结构
C++学习笔记,主要介绍了程序流程结构,包括顺序结构、选择结构和循环结构。选择结构中详细解释了if语句、三目运算符和switch语句的用法和注意事项。循环结构部分则涵盖了while循环、do-while循环和for循环的语法和使用技巧。此外,还介绍了跳转语句,包括break、continue和goto语句的用途和用法。
28 0
|
2月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
77 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
3月前
|
C语言 图形学 C++
|
3月前
|
编译器 C++
C++:继承性_程序
C++:继承性_程序
26 1
|
3月前
|
存储 算法 程序员
【C++进阶】深入STL之vector:构建高效C++程序的基石
【C++进阶】深入STL之vector:构建高效C++程序的基石
42 1