Effective C++阅读笔记
文章平均质量分 52
ShenHang_
一个编程小菜鸡
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++11 emplace_back(最后又回顾了一下移动构造和移动赋值)
我们在对STL容器进行插入操作时,常会使用insert或push_back。C++11提出了更高效的插入方法:emplace。下面介绍C++11新特性中emplace的使用与原理。vectoremplace <--> insertemplace_back <--> push_backsetemplcace <--> insertmapemplace <--> insert以vector的emplace_back为例:#includ原创 2021-09-13 16:47:54 · 1448 阅读 · 0 评论 -
字符串常量初始化指针的小问题
char a[20] = "1234";cout << a << endl;char *p = a;cout << p << endl;那么该如何得到该字符串的地址呢?cout << (int*)a << endl;cout << &a << endl;这两种方法都可以正确打印出“字符串的地址”,但是有细微区别之处在字符数组a中,a表示第一个字符的地址,a+1表示第二个字符的地址;原创 2021-06-09 22:26:30 · 273 阅读 · 0 评论 -
const_cast的小问题
const_cast只可以对指针和引用使用也许大家都有过这样的疑惑:const_cast可以去除一个常量的const属性,去除const属性后应该可以对“常量”进行修改,通过调试器发现内存中的值是被改变的,可是再传递这个“常量”的时候,值却一直保持原状,这是为什么呢?void fun(int &value){ cout << "Fun(val)=" << value << endl;}int main() { const int val = 10原创 2021-06-09 21:40:40 · 588 阅读 · 1 评论 -
copy ctor、copy assignment(拷贝构造函数和拷贝赋值函数)
这个很早就搞明白了,只是这里系统整理一下。例1:例2:#include<iostream>#include<functional>#include<numeric>using namespace std;// TEMPLATE STRUCT plustemplate<class _Ty = void>struct my_plus{ // functor for operator+ typedef _Ty first_argument_原创 2021-05-08 11:23:27 · 1588 阅读 · 3 评论 -
复习——dynamic_cast(RTTI)
例子1直接看代码:代码1:class Base {public: Base() :b(1) {} virtual void foo() {} int b;};class Derived :public Base{public: Derived() :d(2), Base() {} int d;};void fun(Base*pb){ Derived*pd1 = static_cast<Derived*>(pb);//把基类对象指针下行转换为派生类对象指针原创 2020-05-12 21:18:55 · 291 阅读 · 0 评论 -
复习——虚函数表的实现&typeid
class Base {public: virtual void f() { cout << "Base::f" << endl; } virtual int g() { cout << "Base::g" << endl; return 0; } virtual int h(int a) { cout << "Base::h" << endl; return 0; }};int main(){ typedef vo原创 2020-05-12 14:41:04 · 610 阅读 · 0 评论 -
effective_考虑写出一个不抛出异常的swap函数(涉及到pimpl手法)
很早就接触过最简单的swap函数:#include<iostream>using namespace std;void swap(int&a,int&b) { int temp(a); a = b; b = temp;}int main() { int a = 1, b = 2; swap(a, b); cout << a <&l...原创 2020-01-06 10:36:59 · 239 阅读 · 0 评论 -
派生类的构造函数
例1:#include<iostream>using namespace std;class B {public: B() { cout << "无参构造函数" << endl; } B(int bb):b(bb) { cout << "有参构造函数" << endl; }private: int b;};class ...原创 2020-01-04 17:17:30 · 491 阅读 · 0 评论 -
effective_别让异常逃离析构函数
条款08:别让异常逃离析构函数1.析构函数绝对不要吐出异常。如果一个析构函数内调用的函数可能抛出异常,析构函数应该捕捉任何出现的异常,然后选择吞下它们或结束程序,别让异常逃离析构函数。2.如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中),让客户自己去调用该操作函数,给客户一个处理错误的机会。(见例2)例1:class Widget...原创 2020-01-04 15:23:14 · 280 阅读 · 0 评论 -
避免异常发生时的堆内存泄漏——智能指针auto_ptr
自己编的两个小例子,感觉贼好懂_!#include<iostream>using namespace std;enum index { underflow, overflow };//index是枚举类型int array_index(int *a, int n, int index);void fun() { int n = 10; int *a = new int[n...原创 2020-01-03 19:48:45 · 416 阅读 · 0 评论 -
C++的标准程序库异常处理
C++标准提供了一组标准异常类,这些类以基类exception开始,标准程序库抛出的所有异常,都派生与该基类,这些类构成如图所示的异常类的派生继承关系。该继承类提供一个成员函数what(),用于返回错误信息(返回类型为const char*)。在exception类中,what()函数的声明如下:virtual const char* what() const throw();该函数可以在派...原创 2020-01-03 12:31:12 · 539 阅读 · 0 评论 -
throw、try、catch 异常处理机制、栈的解旋
1)若有异常则通过throw操作创建一个异常对象并抛掷。2)将可能抛出异常的程序段嵌在try块之中。控制通过正常的顺序执行到达try语句,然后执行try块内的保护段。3)如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行。程序从try块后跟随的最后一个catch子句后面的语句继续执行下去。4) catch子句按其在try块后出现的顺序被检查。匹配的catch子句将捕...原创 2020-01-02 21:37:11 · 1289 阅读 · 0 评论 -
effective_为多态基类声明虚析构函数
条款07这里需要补充的知识点(我觉得很重要):一.如果一个类不企图被当作基类,那么令其析构函数为虚函数是很愚蠢的。正确的做法应该是:只有当类中有至少一个虚函数时,才把其析构函数声明为虚析构函数。因为虚函数的作用是为了动态联编(实现多态),而为了实现动态联编,对象需要额外多出vptr指针,会增加体积(sizeof可以明显看出),vptr指向一个由函数指针构成的数组,称为vtbl(虚表),每一个带...原创 2019-12-28 22:13:33 · 279 阅读 · 0 评论 -
C++派生类的复制构造函数和赋值运算符函数(个人理解)
下面我的程序其实本质上就是模拟了默认的派生类复制构造函数和默认的派生类赋值运算符函数的实现。#include<iostream>using namespace std;class B {private: int b;public: B(int bb = 0) :b(bb) {} B(const B&obj) :b(obj.b) {} B& operat...原创 2019-12-24 11:57:12 · 981 阅读 · 0 评论 -
effective_若不想使用编译器自动生成的函数,就该明确拒绝
条款06:若不想使用编译器自动生成的函数,就该明确拒绝.(Explicitly disallow the use of compiler-generated functions you do not want)首先给出一个类的定义:class HomeForSale{};我们的目的:阻止默认复制构造函数和赋值操作符的调用,即要使以下语句无法执行:HomeForSale h1;Home...原创 2019-12-24 09:47:04 · 170 阅读 · 0 评论 -
虚函数与动态联编、纯虚函数与抽象类、虚析构函数——笔记补充
使用场景:当使用基类对象的指针指向派生类的对象或使用基类对象的引用作为派生类对象的别名,并通过基类指针或基类引用访问某个与基类同名的成员函数时,需要在基类中将这个同名函数说明为虚函数。例1:#include <iostream>using namespace std;class A {private: int a;public: A(int i=1):a(i){} ...原创 2019-12-23 19:34:47 · 229 阅读 · 0 评论 -
虚基类——解决继承的菱形问题
1.如果按普通的继承方式,那么可以写出以下程序:#include<iostream>using namespace std;class B {protected: int b;public: B(int bb = 0) :b(bb) { cout << "基类B的构造函数被调用" << endl; } void display() { cout...原创 2019-12-23 10:48:58 · 325 阅读 · 0 评论 -
派生类的对象赋值给基类对象
派生类对象隐含转换为基类对象,即用派生类对象中从基类继承来的成员,逐个赋值给基类对象的成员。注意:public继承方式下,基类的private成员,在派生类中虽然无法访问,但是还是客观存在的!!!。如果一定要通过派生类对象访问基类的private成员,那么只能在基类中设置一个公有接口。自己写了一个程序例子,觉得很清楚了(这里还涉及到了静态联编):#include<iostream>...原创 2019-12-18 21:19:37 · 4928 阅读 · 0 评论 -
effective_对象的初始化细节
effective C++条款04首先放上一段存在多义性的代码:class point {public: point() {} point(int xx = 0, int yy = 0):x(xx),y(yy){}private: int x, y;};int main() { point p; system("pause"); return 0;}显然编译时报错,因...原创 2019-12-10 21:10:19 · 291 阅读 · 0 评论 -
effective_在none-const和const成员函数中避免重复
1.static_cast用法:static_cast < type-id > ( expression )该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针...原创 2019-12-10 16:16:47 · 272 阅读 · 0 评论 -
effective_operator= 为什么要返回引用
以一个具体例子进行说明:class complex {public: complex(double r = 0., double i = 0.) :real(r), image(i) { cout << "构造" << endl; } complex(complex&c) :real(c.real), image(c.image) { cout <&l...原创 2019-12-10 14:28:08 · 249 阅读 · 0 评论 -
effective_const成员函数与mutable变量
当在c++中,定义类时,对一个函数使用const进行修饰后,该函数将无法修改类成员变量的值,但对mutable修饰的成员变量没有这个限制。class Test {private: mutable int value;public: Test(int a=0):value(a){} void setvalue(int a) const; void print() const;};...原创 2019-12-09 16:50:19 · 183 阅读 · 0 评论 -
effective_类内的静态常量和静态变量使用
代码如下:#include<iostream>using namespace std;class A {public: static const int num1 = 1;//静态常量声明式(静态常量可以直接在类内初始化) static int num2;//静态变量声明式(静态变量在类内声明,类外定义和初始化) int score[num1];};const i...原创 2019-12-08 22:08:44 · 134 阅读 · 0 评论 -
effective_指针常量、常量指针和常量指针常量
1.指针变量:指针值可以改变的指针,只能指向变量;2.指针常量:指针值不能改变的指针,只能指向变量,但可以修改指向的实体变量的值;3.常量指针:指向常量的指针,所以不能修改指向的实体的值,但可以修改指针值(即可以指向别的常量,必须是常量);4.常量指针常量:指向常量,指针不能改变指向的实体的值,指针值也不能改变(是2和3的结合)。const int a = 78; //整型常量in...原创 2019-12-08 20:52:09 · 164 阅读 · 0 评论 -
effective_隐式构造函数以及赋值函数和复制构造函数的区别和实现
如果C++类的其中一个构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象。#include<iostream>using namespace std;class complex { double real, img;public: complex():real(0.),img(0.) {} complex(cons...原创 2019-12-08 19:38:25 · 261 阅读 · 0 评论
分享