Effective C++的学习(条款1-4)
Posted sujian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Effective C++的学习(条款1-4)相关的知识,希望对你有一定的参考价值。
零、导读
1.explicit在构造函数中的使用
目的:阻止构造函数被用来隐式类型转换
class A{ public: explicit A(int a=0,int b = 1){} //非隐式 } void f(A c); A a; f(a); //没有问题 f(18); //报错,18不会被转换为A对象的实例,去掉explicit成功
一般来说都要写成非隐式的,除非有特殊需要
2.拷贝构造与拷贝赋值(operator=)
拷贝构造一般参数为引用,传值的话会先调用拷贝构造,再传值,比较麻烦。
拷贝赋值一般返回值为引用。
条款01:视C++为一个语言联邦
四个次语言:
1.C 2.Object-Oriented C++ 3.STL 4.Template C++
使用C中的内置类型,传值比传引用高效,而面向对象相反
条款02:尽量以const,enum,inline替换 #define
1.内容:宁可以编译器替换预处理器(#define时预处理器要处理的内容)
2.常量优点:
①.出现问题时可以在符号表中对应找到,而宏定义只能显示定义内容
②.使用常量只会产生少量的码,简单很多(具体还需要查一查)
3.常量替换的两种特殊情况
①定义常量指针
②class专属常量(需要先声明,然后在定义(放在实现文件中),记住要声明为static,使所有实例化对象都访问这一个常量(分配内存只需要一次)),#dedine不提供封装性
4.#difine还可以用enum替换
①两者同样不可取地址,而常量可以
5.宏定义函数要用内联函数替换
条款03:尽可能使用const
1.三种形式:
①const type* 指物不变
②type* const 指针不变
③指针指物都不变
2.STL迭代器的两种形式
①const std::vector<int>::iterator iter = vec.begin() 指针不变,可以给*iter赋值
②std::vector<int>::const_iterator iter = vec.begin()指物不变,可以给iter赋值
3.功能
①可以避免像是"=="输入成"="的错误
例子:const int operator*(int a,int b) (a*b=c)报错,原因a*b不可被赋值
4.const成员函数(标记该成员函数是否可以改变对象内容,const在函数最右)
①两种观点:
1)bitwise(physical) constness:函数没有直接改变成员内部,但是却给了间接改变的机会,如返回成员的引用
2) logical constness:使用mutable声明成员,使得const函数可以改变成员
5.const和non-const成员函数避免重复(方法在条款27)
问题:如果定义了相同功能,但是修改权限不同的两个函数(const,非const),这两个函数在代码段上相同,会产生大量重复
方法:用non-const函数去调用const函数(不能反向)
原因:const调用non-const还是会使得成员发生改变,这是编译器不允许的,反之可以
条款04:确定对象被使用前已先被初始化
1.内置类型在使用时要初始化,因为不确定会被随机成什么内容
2.对象初始化,使用构造函数
①不要混淆初始化与赋值(初始化列表为初始化,构造函数内部为赋值)
②尽量使用初始化列表进行初始化
③初始化顺序为成员声明顺序
3.non-local static对象(全局静态对象)
多个编译单元中,如果其中一个编译单元全局静态对象的初始化动作使用了另一个编译单元全局静态对象,而后者可能还没初始化,这时会出错,因为不同编译单元中初始化顺序不确定。
初始化时使用构造函数,确保对象一定创建成功(以local static换non-local static)
以上是关于Effective C++的学习(条款1-4)的主要内容,如果未能解决你的问题,请参考以下文章