值语义与对象语义
【1】什么是值语义?
所谓值语义是指目标对象由源对象拷贝生成,且生成后与源对象完全无关,彼此独立存在,改变互不影响。就像 int 类型变量相互拷贝一样。
C++的内置类型(bool/int/double/char)都是值语义,标准库里的 complex<>、pair<>、vector<>、map<>、string 等等类型也都是值语义。
拷贝之后就与源对象完全脱离关系。
【2】什么是对象语义?
对象语义也叫指针语义,引用语义等。
通常是指一个目标对象由源对象拷贝生成,但生成后与源对象之间依然共享底层资源,对任何一个的改变都将随之改变另一个。
就像包含有指针成员变量的自定义类在默认拷贝构造函数下对其对象之间进行的拷贝。拷贝后目标对象和源对象的指针成员变量仍指向同一块内存数据。
如果当其中一个被析构掉后,另一个对象的指针成员就会沦为名副其实的悬垂指针!
又比如,Thread 是对象语义,拷贝 Thread 是无意义的,也是被禁止的:因为 Thread 代表线程,拷贝一个Thread对象并不能让系统增加一个一模一样的线程。
【3】两者之间的联系
“值” 与 “对象”类型之间并没有严格定义的区分。但通常可以观察到下列不同:
值 是 死的、 傻的、 简单的、 具体的、 可复制的
对象 是 活的、 聪明的、 复杂的、 抽象的、 不可复制的
这里的“复杂性”主要还是指行为的复杂性,而非结构的复杂性。例如,
list< map< vector<string>, deque< set<int> > > >
仍然是一个不折不扣的“值”类型。
值语义的一个巨大好处是生命期管理很简单,比如 int 类型一样——你不需要操心 int 对象 的生命期。
值语义的对象要么是栈对象,或者直接作为其它对象的数据成员,因此我们不用担心它的生命期(一个函数使用自己栈上的对象,一个成员函数使用自己的数据成员变量)。
相反,对象语义的 对象由于不能拷贝,我们只能通过指针或引用来使用它。
一旦使用指针和引用来操作对象,那么就要担心所指的对象是否已被释放,这一度是C++程序bug的一大来源。
此外,由于C++只能通过指针或引用来获得多态性,那么在C++里从事基于继承和多态的面向对象编程有其本质的困难——内存资源管理。
Good Good Study, Day Day Up.
顺序 选择 循环 总结