作者回复: 把C++当作一种工具,也当作一种锻炼思维的方式,不要把它当成非用不可的圣器。把自己定位成“程序员”,而不是“C++程序员”。职业的将来方向定位成“软件架构师”、“开发主管”、“CTO”之类的角色,而不是“高级C++程序员”。
该用其他语言的时候用其他语言。要看到,即使不用C++,C++程序员在对优化的理解、对内存管理的理解等方面都是具有很大优势的。
作者回复: 是。👍
作者回复: 理解满分。👍
作者回复: 1. “通常”。字符串字面量是个继承自C的特殊情况。
2. 这个搜索一下就行。这是CPU的缓存结构决定的。
3. 其他类,尤其容器类,会期待移动构造函数无异常,甚至会在它有异常时选择拷贝构造函数,以保证强异常安全性。
作者回复: 对,最主要就是这点,用完美转发来正确调用构造函数。
作者回复: 再多说一句,如果每个人都这么让我来看笔记的话,我是不可能满足所有人的。只看你的,也对别人不公。在这儿回答(不重复的)问题则不同,问题一般是有共性的,回答之后,大家都能看到,都能从中受益。
作者回复: 你在学校的时候,都是让老师来看你的笔记记得好不好的吗?😂
对不起,如果有明确的问题,我可以回答。否则,我只能暂时忽略了。
作者回复: 对,x = 1 和 ++x 返回的都是对 x 的 int&。x++ 则返回的是 int。
作者回复: 因为移动发挥威力了……试试把 std::string("hello") 放到 test2 开头作为变量,然后后面使用这个变量。
作者回复: 中间传的都是引用,没有拷贝或移动发生的。只有用Obj(而不是Obj&或Obj&&)作为参数类型才会发生拷贝或移动构造。
作者回复: 文中已经说了,禁止返回本地对象的引用。
需要生成一个 Obj,给了一个 Obj&&,不就是调用构造函数而已么。所以(看文中输出),就是多产生了一次Obj(Obj&&) 的调用。
作者回复: 不是。Java里没有右值,也不必要有右值。因为Java里的对象都是引用语义,从来不是值语义。再仔细看一下。
作者回复: 2完全正确。1再想想。🤓
作者回复: 联合第四点一起看。对象 3 一般不是临时对象。
作者回复: 就是字符串指向的内存区域被类似于 strcpy 或 memcpy 的调用复制了几次。
作者回复: 是这样的。在第 10 讲中有一个更完整的讨论,你也可以参考一下。
作者回复: 试试不就知道了?😉
字符串常量是常左值,有确定的地址。常左值能不能放等号左边呢?我不需要回答了吧。
作者回复: 直观理解,函数已经要返回了,本地对象已经没用了,编译器选择最有效的返回数据方式:第一是返回值优化,第二是移动,第三才是拷贝。
这就是我文中所写的:“在 C++11 之前,返回一个本地对象意味着这个对象会被拷贝,除非编译器发现可以做返回值优化(named return value optimization,或 NRVO),能把对象直接构造到调用者的栈上。从 C++11 开始,返回值优化仍可以发生,但在没有返回值优化的情况下,编译器将试图把本地对象移动出去,而不是拷贝出去。”
作者回复: 你返回的是一个对象,prvalue,不是左值。这个对象会被移动返回。可以参见第 10 讲。
如果你把返回值改成左值引用,返回的才是左值。在这种情况下,随机的崩溃就可能会发生了,因为被引用的对象已经被销毁。这也是为什么必须返回对象而不是引用,这样的对象会从返回内容移动或拷贝产生。