“事先声明”、“分别编译”、“事后链接”
1) 前置返回一个引用,后置返回一个对象
// ++i实现代码为:
int& operator++()
{
*this += 1;
return *this;
}
2) 前置不会产生临时对象,后置必须产生临时对象,临时对象会导致效率降低
//i++实现代码为:
int operator++(int)
{
int temp = *this;
++*this;
return temp;
}
对左值和右值的一个最常见的误解是:等号左边的就是左值,等号右边的就是右值。左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。
一个区分左值与右值的便捷方法是:看能不能对表达式取地址,如果能,则为左值,否则为右值。
在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
std::forward_list,和 std::list 的双向链表的实现不同,std::forward_list 使用单向链表进行实现,提供了 O(1) 复杂度的元素插入,不支持快速随机访问(这也是链表的特点),也是标准库容器中唯一一个不提供 size() 方法的容器。
当不需要双向迭代时,具有比 std::list 更高的空间利用率。
https://link.zhihu.com/?target=https%3A//blog.csdn.net/laozhong110/article/details/6402574
class CA
{
public:
int fun()
{
int i = 0;
return i;
}
};
CA *pca = NULL;
pca->fun(); //访问ok
一句话记住三者:对象不存在,且没用别的对象来初始化,就是调用了构造函数;
对象不存在,且用别的对象来初始化,就是拷贝构造函数(上面说了三种用它的情况!)
对象存在,用别的对象来给它赋值,就是赋值函数。
参考https://blog.csdn.net/zcyzsy/article/details/52132936
参考https://blog.twofei.com/496/
对于在函数体中初始化,是在所有的数据成员被分配内存空间(并初始化)后才进行的。列表初始化是给数据成员分配内存空间时就进行初始化。
前者是初始化、赋值;后者是初始化;少了一个步骤,当然更快;
类成员变量初始化时按照类中声明的顺序初始化的,而不是按照初始化列表的排序方式。
答:因为静态变量在main之前就已经在全局数据段产生的,它不应该去依赖类对象的生命周期。若是在类内初始化,说明需要等待该类实例化才初始化。因此在类外初始化,程序编译时就已完成。
拷贝(缺省、拷贝、赋值)、析构;
Empty(); // 缺省构造函数//
Empty( const Empty& ); // 拷贝构造函数//
~Empty(); // 析构函数//
Empty& operator=( const Empty& ); // 赋值运算符//
本文探讨C++构造函数体内初始化与列表初始化的区别:
结论是:
若某个类(下文的class B)有一个类成员是类类型(下文的class A),那么
1、若类B通过构造函数体内初始化,会先调用类A的默认构造函数(无参构造函数),再调用类A的赋值运算符;
2、若类B通过初始化列表去初始化,则只调用类A的拷贝构造函数。
另外,虽然对于成员类型是内置类型的情况,通过上述两种情况去初始化是相同的,但是为了标准化,推荐使用初始化列表。
以下几种情况必须使用初始化列表去初始化类成员:
当初始化一个reference member时,即成员类型是引用。
当初始化一个const member时,即成员类型是常量。
当调用一个基类的constructor,而它拥有一组参数时。如果此时不使用列表初始化,那么就需要自己重载赋值运算符。
当调用一个类成员的constructor,而它拥有一组参数时。
若某个类成员没有定义无参构造函数,而定义了其它的构造函数,也必须使用初始化列表。
C++构造函数体内初始化与列表初始化的区别_西塔666的博客-CSDN博客_c++列表初始化与构造函数区别
参考C++ 内存分配(new,operator new)详解 - 王小北 - 博客园
为什么多线程读写 shared_ptr 要加锁? - 陈硕的Blog - C++博客
总结,“析构”算写操作;先找出公共资源对象,然后构造多线程对这个公共资源进行读写,比如share_ptr
Boost.SmartPtr: The Smart Pointer Library - 1.73.0
C++面试宝典(1) - 知乎