读C++ Common Knowledge(五)
sshong 发表于2008年1月13日 21:04:00 更新于2008年3月21日 17:51:00
11、编译器在类中添加了材料(The compiler puts stuff in classes)
对于一个类,通常并不是你看见的就是你所获得的,举个例子,对于一个有虚函数的类,它的对象都将含有一个指向虚函数表的指针。而且各种不同的编译器将虚函数指针位于对象的不同位置,永远不要做一些愚蠢的假设某个成员变量的偏移、虚函数表指针偏移是多少!如:
赋值仅仅发生在你赋值的时候,而其他的包含声明时初始化、函数返回对象、参数传递对象、捕获异常等等都是初始化!
不仅二者使用的场景不一样,他们所做的事情也不一样!(当然在内嵌类型如int double中是看不出差别的,都仅仅是复制一些bits)。
赋值首先要清空原先存储的内容,因此操作者要保证不要对一个没有初始化的对象进行赋值(因为赋值操作可能要delete一些内存)!(看上去有点像首先析构然后构造,有些人干脆对赋值函数首先显示调用析构,然后利用new来调用构造,这样做是不安全的!)
13.拷贝操作(Copy Operations)
拷贝构造和拷贝赋值是两个不同的操作,但他们经常一起出现。
如:
对于一个类,通常并不是你看见的就是你所获得的,举个例子,对于一个有虚函数的类,它的对象都将含有一个指向虚函数表的指针。而且各种不同的编译器将虚函数指针位于对象的不同位置,永远不要做一些愚蠢的假设某个成员变量的偏移、虚函数表指针偏移是多少!如:
12.赋值与初始化是不相同的(Assignment and initialization are different)class T
{
int a;//offset of a is unknown
virtual void f();//offset of vptr(pointer to vitual funnction table) unkonwn
}
赋值仅仅发生在你赋值的时候,而其他的包含声明时初始化、函数返回对象、参数传递对象、捕获异常等等都是初始化!
不仅二者使用的场景不一样,他们所做的事情也不一样!(当然在内嵌类型如int double中是看不出差别的,都仅仅是复制一些bits)。
赋值首先要清空原先存储的内容,因此操作者要保证不要对一个没有初始化的对象进行赋值(因为赋值操作可能要delete一些内存)!(看上去有点像首先析构然后构造,有些人干脆对赋值函数首先显示调用析构,然后利用new来调用构造,这样做是不安全的!)
13.拷贝操作(Copy Operations)
拷贝构造和拷贝赋值是两个不同的操作,但他们经常一起出现。
如:
也就是说二者之间产生的效果应该是相同的!标准容器类的实现,经常采用拷贝构造替换拷贝赋值。对于拷贝赋值通常首先检测是否是等于自己,以保证等号左右两边有不同的地址。如:class Handle{
public:
Handle(const Handle&);//拷贝构造函数
Handle& Operator =(const Handle&);//拷贝赋值
}
Handle a=...;
Handle b(a);//(拷贝构造)
Handle b; b=a;//赋值
Handle& Handle::operator =(const Handle &that){
if(this != &that)
//...do assignment
return *this;
}
评论
暂无评论添加评论
分类
琐碎文字 As3&Flex RIA UG English CodingArt C++ PHP Webserver E音乐盒 Unity3d C# JS&Html5 Tools mobile golang AI 最近发表
- claude code / codex的一些配置(2026年5月5日 17:38:10)
- 2026年5月5日(2026年5月5日 17:27:39)
- js的锁以及异步调用相关(2024年11月30日 10:58:51)
- golang学习之函数/方法/接口(2022年1月6日 17:50:24)
- golang学习之零值(2022年1月6日 16:38:10)
- hello, 2018(2018年1月15日 22:47:25)
- 字体类型名词解释(2015年1月18日 11:29:14)
- 获取mysql表注释以及列注释(2014年11月13日 15:56:32)
- php连接ms sql数据库的一些问题(2014年9月15日 20:32:14)
- virtualbox虚拟网络:NAT&bridge桥接网络(2014年8月25日 22:51:35)
最近回复