关于值语义和对象语义
说个在 c 艹中经常遇见的问题.
在 c++ 中和 c# 和 java 不很一样. 它允许程序员定义一个类的复制构造函数和复制赋值运算符, 这就表明对象是可以复制的. (这里的复制的意思是克隆一个完全一致, 但却是一个新的个体的对象)
这就允许程序员把对象当成值一样来使用, 例如:
1 | string a = "hahaha"; |
在这段代码中, string 和 int 使用起来没有差别, 令 j = i 确实是在内存上新申请了一个 int 的空间, 令他和 i 相等. 同理 string b 也是这样.(也就是复制之后和原对象脱离关系, 就像复制 int 一样)
虽然我知道 string 使用 class 来定义的, int 是 c 语言内置类型, 但是用起来却是完全一致.
另外, 你可以吧 string 放入 vector 中放入 map 中, 就和使用一个 int 一样简单.
所以 string 可以说是值语义的.
另外的一种用法就是在面向对象中比较常见的一种了. 就是用 class 定义一个具体的对象, 比如一个 TCP 连接, 一个文件对象.
我在前几天写程序时想要简单封装一个 tcp 连接的时候, 就陷入了一会遐想, 到底怎么定义复制构造函数和复制运算符. 答案是不要定义
因为复制一个对象在语义上本身就是不对的, 复制一个 tcp 连接是什么意思? 新打开一个连接?
所以说对于这种对象应该禁止他们的复制操作. 最好的方法是继承 boost::noncopyable.
那么, 不能复制了, 我想把 tcp 连接放入 vector 或者在函数中传递怎么办? 我是用的方法是统一使用 shared_ptr, 这样资源泄漏的问题也就解决了.
所以, 在实现一个资源相关的类时, 用 RAII 方法封装一下资源, 然后继承 noncopyable 应该能解决大部分问题.