条款11 在operator=中处理“自我赋值”
自我赋值
证同测试:
if(this==&rhs)return*this;
影响并行处理效率
记住副本:
type* memberO=member;
pmember=new type(*rhs.member);
delete memberO;
return *this;
copy and swap:
class_type temp(rhs);
swap(rhs);
return *this;
条款30看不明白
条款39:明智而审慎地使用private继承
private继承只是一种代码实现方式而没有任何的意味
如果需要一个不含virtual函数和non-static成员变量的空基类,则可以使用private继承,表示EBO(empty base optimization,空白基类最优化)
条款40:明智而审慎地使用多重继承
钻石继承可以用virtual public解决
virtual bases的继承体积会变大,速度会变慢,所以尽量不要用,如果要用,尽可能避免在其中放置数据,类似于Java的接口
条款41:了解隐式接口和编译器多态
对classes而言接口是显式的,以函数签名为中心,多态则是通过virtual函数发生于运行期。
对template参数而言,接口是隐式的,奠基于有效表达式。多态则是通过template具现化和函数重载解析(function overloading resolution)发生于编译期。
特化:开一个特殊的模版类
const解引用获得右值
vector
第一个元素获得1,否则扩容成两倍,将元素逐个地从旧内存复制到新内存,然后将旧内存中的对象析构,且提供强异常安全保证。
《Effective Modern C++》:C++11之后能移动则移动,必须复制才复制,其中实现利用noexcept
,使用std::move_if_noexcept
和std::is_nothrow_move_constructible
校验后移动。
deque
为多个缓冲区,sort时先搬到一个vector然后排序完搬回,使用一个索引表保存缓冲区
stack
template<class T,class Sequence=deque<T> >
默认底层实现为deque,可以传参实现其他构造
stack不提供迭代器
queue
同stack
heap
使用vector实现的堆,也可以使用array
priority_queue
底部是max-heap
slist
单向链表
set
底层红黑树,使用insert_unique()
map
底层红黑树,使用pair,按键值排序
multiset
和set基本相同,使用insert_equal()
multimap
和map基本相同,使用insert_equal()
条款1:理解模版型别推导
在模版型别推导过程中
int&
和const int&
),右值会被推导为原类型(例如int
),然后进行引用折叠。const
和volatile
等饰词会被去掉。数组退化成指针时,如果使用引用传递实参,则可以获得数组型别:
template<typename T>
void f(T ¶m);
const char name[] = "J. p. Briggs";
f(name);
T的型别推导结果是const char [13]
,f的形参型别被推导为const char (&)[13]
。
可以创造出一个模板推导数组含有的元素个数:
template<typename T, std::size_t N>
constexpr std::size_t arraySize(T (&)[N]) noexcept {
return N;
}
int keyVals[] = {1, 3, 7, 9, 11, 22, 35};
int mappedVals[arraySize(keyVals)];
条款2 理解auto型别推导
auto x{27}
代表一个std::initializer_list
,但模版类型推导却不会条款3 理解decltype
decltype(auto)
中auto
表示欲实施推导的型别,推导过程采用decltype
的规则
Widget w;
const Widget& cw = w;
auto w1 = cw; // 去掉饰词,推导为Widget
decltype(auto) w2 = cw; // 理解为auto表示cw,decltype表示完美获取型别,型别为 const Widget&
条款8 优先选用nullptr,而非0或NULL
0和NULL在重载时会调用f(int)
而非f(void*)
,nullptr
的实际型别时std::nullptr_t
,而std::nullptr_t
可以隐式转换到所有的裸指针型别,这就是为何nullptr
可以扮演所有型别指针的原因。
条款9 优先选用别名声明,而非typedef
tpyedef
不支持模板化,别名声明支持::type
后缀,且不需要typename
前缀一些类型变换工具:
std::remove_const_t<T>
std::remove_reference_t<T>
std::add_lvalue_reference_t<T>
条款12 为意在改写的函数添加override声明
如题
成员函数引用饰词使得对于*this
为左值或右值时区别对待
DataType &data() &{ return values; }
DataType data() &&{ return std::move(values); }
条款15 只要有可能使用constexpr,就使用它
constexpr
对象具备const属性,且在编译阶段就已知(严格说是翻译阶段)。
constexpr
函数在调用时若传入的实参值是编译器已知的,则会产出编译期结果。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章