- 博客(19)
- 收藏
- 关注
转载 Effective C++ 14:资源管理类要特别注意拷贝行为
被复制时情况会怎样?把当前作用域的代码加入到同一个临界区中?拷贝互斥锁并定义一个新的临界区?还是简单地给互斥锁换一个资源管理者?智能指针可以有不同的拷贝策略。当你实现这样一个资源管理对象时,需要特别注意。该互斥锁的使用方式很简单,只需要为每个临界区创建一个C++代码块,在其中定义。如有疏漏、谬误、侵权请通过评论或 邮件 指出。中提出了基于RAII的。
2023-08-09 00:01:34 94 1
转载 Effective C++ 13:使用对象来管理资源
利用C++中对象自动析构的特性,自动地释放资源。C++编译器并未提供自动的垃圾回收机制,因此释放资源的责任落在了开发者的头上。函数把释放资源的责任交给了客户,但并未显式地声明这一点,因而客户有时并不知情。幸运的是,我们可以用对象来包装资源,并在析构函数中释放它。它在没有任何其他指针引用到该资源时,进行资源的释放。虽然智能指针有这样的问题,但C++并未提供管理数组的智能指针,因为。的容器也是不允许的: 可以创建这样的容器,但往里面添加元素(例如。退出作用域,析构函数被调用,最终使得资源被释放。
2023-08-08 23:48:28 108
转载 Effective C++ 12:完整地拷贝对象
你可能注意到了代码的重复,但千万不要让复制构造函数和赋值运算符相互调用,它们的语义完全不同!反过来让复制构造函数调用赋值运算符倒是可以编译, 但由于复制构造函数的前置条件是一个未初始化的对象,而赋值运算符的前置条件是一个已初始化的对象。这样的调用并非好的设计,恐怕会引起逻辑混乱。便被被你忽略了,编译器也不会给出任何警告(即使在最高警告级别)。),默认的拷贝函数确实会完整地拷贝对象,但有时我们选择重载拷贝函数,问题就出在这里!如有疏漏、谬误、侵权请通过评论或 邮件 指出。总之当你实现拷贝函数时,
2023-08-08 23:36:01 96
转载 Effective C++ 11:赋值运算符的自赋值问题
这样一来自赋值的判断也不需要了,当然如果你关心效率,也可以添加自赋值判断。但这一点需要权衡:代码量的增加和判断语句都会影响指令的执行效率,例如指令预取、指令缓存、流水线都会变得更低效。之所以会出现自赋值的问题,是因为C++允许变量有别名(指针和引用),这使得一个数据可以有多个引用。自赋值看起来像是不正确的调用方式, 但是在C++中这是合法的而且常常是不可识别的。如果我们选择重载一个类的赋值运算符,要注意在自赋值时仍然能够正确工作。总结一下,赋值运算符的重载要注意自赋值安全和异常安全。,如何实现异常安全的。
2023-08-08 23:16:15 150
转载 Effective C++ 10:赋值运算符要返回自己的引用
运算符是右结合的,链式赋值时会从右向左运算。链式写法的赋值已经成为了惯例,所以我们自定义的对象最好也能支持链式的赋值,这需要重载。说到运算符的结合性,不妨来研究一下最费解的运算符。如有疏漏、谬误、侵权请通过评论或 邮件 指出。,此时第一个表达式变成了。上述代码的输出结果是。
2023-08-07 00:29:07 73 1
转载 Effective C++ 9:在析构/构造时不要调用虚函数
可见,子类对象在父类构造时期,运行时类型确实为父类。与此同时,dynamic_cast也会解析到父类,父类构造函数中调用虚函数就是例子~父类构造期间,对虚函数的调用不会下降至子类。如果这并非你的意图,请不要这样做!,因此调用子类的函数是不安全的,因此C++不允许这样做。其实,对于构造函数中直接的虚函数调用,某些编译器会发出警告。这一点很好理解,因为父类对象会在子类之前进行构造,此时。不仅虚函数会被解析至父类,运行时类型信息也为父类(那是一个纯虚函数,因此程序会非正常退出。在构造时,调用到父类。
2023-08-07 00:19:37 69 1
转载 Effective C++ 7:将多态基类的析构函数声明为虚函数
大小为1,故总的大小以8为基对齐,大小为8*2 = 16。值得一提的是虚函数表指针的内存占用问题,我们知道所有存在虚方法的对象中都会存有一个虚函数表指针。包含对象成员的类称为封闭类,封闭类以对象成员中最大的基本数据类型的长度进行字节对齐。说道对象大小,来总结一下字节对齐的问题吧,也是笔试面试的常见题型。同时,每个存在虚方法的类也会对应一个虚函数列表的指针。大小是2,故总的大小以4为基对齐,大小为4*2 = 8。的类型),其大小为8,故以8为基对齐的结果是8*3 = 24。的大小是平台相关的。
2023-08-04 01:15:04 52 1
转载 Effective C++ 6:禁用那些不需要的缺省方法
在C++中,编译器会自动生成一些你没有显式定义的函数,它们包括:构造函数、析构函数、复制构造函数、=运算符。这些默认生成的函数给我们的类提供了缺省的功能,比如赋值、复制、构造、析构等;同时也给我们重载这些函数的机会,借此实现更加复杂的对象行为。在编译器默认生成的拷贝构造函数和赋值运算符中,会调用父类的相应函数。然而这些调用将会被拒绝,因为对父类这些函数的访问将被拒绝。比如对于一个单例而言,我们不希望它能够被直接构造,或者拷贝。这里我们来实现一个不可拷贝的类。的不可拷贝特性是可以继承的。
2023-08-04 01:01:49 52 1
转载 Effective C++ 5:那些被C++默默地声明和调用的函数
在C++中,编译器会自动生成一些你没有显式定义的函数,它们包括:构造函数、析构函数、复制构造函数、运算符。有时为了符合既有设计,我们不希望自动生成这些函数,我们可以把它们显式声明为private。此时在使用这些类的客户看来,它们就像不存在一样。这些编译器自动生成的缺省方法是可以禁用的,把它们声明为private便能解决绝大多数问题。
2023-08-04 00:56:24 66 1
转载 Effective C++ 4:确保变量的初始化
出于效率原因,C++不保证的初始化。但成员对象会在构造函数进入之前进行初始化。其中数据成员a是基本数据类型,会执行,最终保有不确定的值。b是对象类型,总会被初始化,它的无参数的构造函数将被调用。有成员对象的类称为封闭类(Enclosing Class,这里C就是一个封闭类),如果B没有不带参数的构造函数,则必须在C的构造函数中进行b的初始化。。
2023-08-02 23:21:49 67
转载 Effective C++ 3:尽量使用常量
尽量使用常量。不需多说,这是防卫型(defensive)程序设计的原则, 尽量使用常量限定符,从而防止客户错误地使用你的代码。
2023-08-02 23:09:42 45
转载 Effective C++ 2:避免使用define
尽量使用常量、枚举和内联函数,代替#define。我们知道#define定义的宏会在编译时进行替换,属于模块化程序设计的概念。宏是全局的,面向对象程序设计中破坏了封装。因此在C++中尽量避免它!接着我们具体来看#define造成的问题。
2023-08-02 22:54:24 56
原创 C++中的trivial和non-trivial构造/析构/拷贝/赋值函数及POD类型
trivial意思是无意义,这个trivial和non-trivial是对类的四种函数来说的: ◦ 构造函数(ctor) ◦ 复制构造函数(copy) ◦ 赋值函数(assignment) ◦ 析构函数(dtor)
2023-03-07 22:45:08 1459 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人