说一个类型具有值语义,当它具有一下特点:1)同类型的两个对象之间可拷贝 2)拷贝之后各自具有独立性。
例如:int a=1; int b=2; b = a; 显然,int类型是值语义,因为我修改b=3不会影响a的值
不可拷贝的对象,不满足条件1),当然就不是值语义,我们给它起个名字:实体语义(Entity Semantic)。
例如:
class CFile{
FILE a_operation_system_file_handle; //一个文件句柄
......
public:
CFile(const CFile&) = delete;
};
实体语义的对象不能作为参数传递给其它函数,因为它不能拷贝。我们换一种引用语义,就可以传递了。例如:
CFile file1
void some_function(CFile& file2){
//....
//change file2
}
some_function(file1);
//... 观察者发现 file1 也发生改变,例如:文件指针位置,文件属性等
虽然CFile不能拷贝,但是CFile&这个衍生类型允许拷贝构造(也是拷贝),我们就会遇到引用语义(ref semantic)。
正如引用类型的行为,两个标志符file1和file2指向同一个东西。
奇异值语义:a=b; assert(a!=b). 拷贝之后,相等比较操作返回false。因为这会让人吃惊,所以应避免奇异值语义。
bit-wise-copy值语义:依靠bit-wise-copy实现的拷贝,例如:
class Dog{
enum color { red, green, blue };
int id;
float weight;
color c;
};
deep-copy值语义:依靠深拷贝实现的值语义。例如:std::string 注:避免COW,会发生在某些时间一个string对象是引用语义,而在另一些时间又变成值语义的。
class String{
char* buf;
public:
String(const String& other){
buf = new char[strlen(other.buf)+1];
strcpy(buf, other.buf);
}
//...一个非常错略的deep-copy值语义的String类型
};
String a("123");
String b = a;
//对b做的任何改动,绝不会影响对象a的状态。
std::shared_ptr智能指针是引用语义。
最后的小测验: std::unique_ptr智能指针是什么语义?
。
。
。
。
。
。
答:是奇异值语义。因为满足值语义的判定条件。并且拷贝后,两个对象的相等比较通不过。