作者回复: 其他都对,不过,自定义delete似乎目前没这个必要?
1. 好问题。静态存储区既不是堆也不是栈,而是……静态的。意思是,它们是在程序编译、链接时完全确定下来的,具有固定的存储位置(暂不考虑某些系统的地址扰乱机制)。堆和栈上的变量则都是动态的,地址无法确定。
2. thread_local和静态存储区类似,只不过不是整个程序统一一块,而是每个线程单独一块。用法上还是当成全局/静态变量来用,但不共享也就不需要同步了。
3. 非静态数据成员加上动态类型所需的空间。注意后者不一定是4,而一般是指针的大小,在64位系统上是8字节。还有,要考虑字节对齐的影响。静态数据成员和成员函数都不占个别对象的空间。
作者回复: 谢谢。这个专栏是要求之前学过、用过C++的。没学过的不合适。
作者回复: 认真记笔记非常好。
不过,建议笔记还是记关键字和要点,解释文字不用多。否则篇幅跟原文接近就意义不大了。
作者回复: 凡生命周期超出当前函数的,一般需要用堆(或者使用对象移动传递)。反之,生命周期在当前函数内的,就该用栈。
作者回复: 如果这个变量下面还有用到的地方,这是个好习惯。不过,这个习惯主要还是从C来的。现代C++不推荐一般代码里再使用裸指针和new/delete的。
作者回复: 哈,你是第一个用这个形容词的。😁
作者回复: 这就是面向对象里的基本用法了。在面向对象的继承体系了,shape需要有一个虚析构函数。这样如果有一个shape*实际指向circle,在delete这个指针时,调用的是circle的析构函数(当然析构过程中,最后也会再调用shape的析构函数)。
下面的代码可以展示这个过程:
#include <stdio.h>
class shape {
public:
virtual ~shape()
{
puts("~shape");
}
};
class circle : public shape {
public:
~circle()
{
puts("~circle");
}
};
int main()
{
shape* ptr = new circle();
delete ptr;
}
结果是:
~circle
~shape
作者回复: 这里主要牵涉到“栈帧”是如何定义的。虽然“参数属于调用者而非被调用者,一般也是由调用者来释放”概念上没有错,但我当时对“栈帧”的定义想当然了。我后来又查了一下定义(用词要以大家接受的用法为准),发现参数和局部变量应该算作一个栈帧里。也就是说,你们这儿的质疑是有道理的。所以,目前我已经把图修改了,这样应该就都没有疑问了。
作者回复: 如果刚开始学的话,这个专栏可能会有点挑战。可以先看一下 C++ 之父的 A Tour of C++,国内出版叫《C++语言导学》(谢谢小猪钱钱同学告知)。
另外,《C++ Primer》名声很响,但 848 页初学有点厚了。注意不是《C++ Primer Plus》,这本跟前者完全无关,不推荐。
作者回复: 是的。
作者回复: 嗯,有点道理。但需要学习能力很强,因为我假设你是懂C++的基本语法的。
作者回复: 一般不这么看。异常安全性对系统有很多约定,违反了约定,通常 terminate 会被调用。这种情况下就是不做清理工作的。
在Windows上,你甚至可以用 catch(...) 捕获指针越界访问(需要 /EHa 编译参数),但前提条件一样是你需要去 catch。
从另一个角度,程序崩溃时,大部分资源都会被操作系统回收,不会对系统造成问题。我们说泄漏,关注的主要是程序(长时间)运行过程中应该释放而没有释放掉的东西,如内存、文件句柄、锁等等。
作者回复: 因你这句话,我特地又去查了一下,目前看到的图,开口永远是上方。中英文资料都是如此。
这个词的来源实际上可能是堆盘子。显然,你只能从上面取放盘子……
作者回复: 是这个顺序。但异常抛出后,如果有相应的catch的话,析构完了才会执行到catch。
作者回复: 看对象多大了。如果对象很大(大数组吗?),那可以把它放堆上;或把里面的大成员放堆上,把对象做成 RAII 管理对象。
作者回复: 我那是示意,构造是不允许这样调用的。
析构的语法则可用,但你这个错误似乎是没把 ptr 当成参数传进去。
作者回复: 不是。返回shape*是没有问题的。返回shape才会造成对象切片。
可以通过delete一个shape*来删除一个circle对象的。这个是正常的面向对象行为。要求是shape有虚析构函数。
作者回复: 1. 恰恰相反,大部分语言里都有像指针的东西,只是不叫指针,不能随意转换和做加减法,也就不那么危险。很多语言都没有值语义——传递对象,而不是对象的指针/引用。
2. 得到一个指针,当然是引用语义。
3. 不是完整表达式,问题没有意义。
作者回复: 是问题之一。
作者回复: 加油!跟Java区别还是很大的,要注意。