C++的构造函数总结
作者:网络转载 发布时间:[ 2015/1/23 11:06:59 ] 推荐标签:C++ net
了解完拷贝构造函数的调用时机,我们再来看看编译器生成的默认拷贝构造函数都做了什么。默认拷贝构造函数主要作用是按位拷贝,在必要的时候,除了按位拷贝,还插入一些其他行为,具体内容请看先前的文章----[C++拷贝构造函数总结](http://www.cnblogs.com/yetuweiba/p/3390853.html)。在实现拷贝构造函数中我们需要注意一点深拷贝和浅拷贝,防止出现的拷贝不完全的错误。
以上是构造函数的语法基础知识点,根据上面的原理,可以总结出来一些容易出错的地方,具体请看下面。
>1.如果对象拥有成员变量,需要在自定义构造函数中设定初值,尽可能地使用成员初始化列表对成员变量进行初始化。同时,成员变量是按照声明的顺序来构造的,所以,要注意依赖。
在构造函数中对成员变量进行初始化的话,在编译器中实际上是先调用此成员变量的构造函数,再调用它的赋值函数,所以,使用成员初始化列表会节省效率。
成员变量的构造是按照声明的顺序进行的,所以,不要让声明早的成员变量依赖声明晚的成员变量。示例如下
class Obj
{
private:
int a;
int b;
// 下面的构造函数是错误的
Obj(const int value)
: a(b + 1) // error,此时b还未构造好,a的值会不可预料。
, b(value) // 正确的做法是调换a和b的声明顺序,在成员初始话列表中也调换a和b的顺序
{}
};
|
>2.谨慎在构造函数中调用虚函数(好不要在构造函数中调用虚函数)。
我们先来举一个例子:
class Base
{
Base()
{
fun();//error,此时调用的是Base的fun,会发生调用错误。
}
virtual void fun() = 0;
};
class Derivate : public Base
{
Derivate(){};
virtual void fun()
{
std::cout << "I am Derivate" << std::endl;
}
};
Derivate d;
|
上面代码中,构造d会发生错误,因为基类早于派生类进行构造,在基类构造的时候,是不会下降到派生类中的,也是此时只会调用基类的函数,而Base中的fun是存虚函数,此时会发生错误。虽然我们可以在Derivate的构造函数中调用fun,但这样做,意味着接口的设计出现了问题。所以,好不要在构造函数中调用虚函数。
>3.在并发环境下,注意构造函数的安全性。
当在并发的环境下,原本简单的事情会变的复杂。我们都知道,在并发环境下,线程的执行是乱序的,我们拿到一个指向对象的指针,这个指针指向的可能是构造函数执行一般的对象,例如:
class Foo : public Observer
{
// error
Foo(Observable * s)
{
s->register(this)
}
}
上面例子的做法是不安全的,因为在构造函数中将自身注册出去,此时对象可能仍未完全构造完。如果,Foo是积累的话,那么注册的时候派生类还没有构造完成,此时也会引发错误。所以,由上例可知:在对象构造期间不要对外暴露this指针(陈硕)。解决上面错误的一个方法是“二段式构造”,即对象构造完成后,再对外暴露this指针。
以上是关于C++中构造函数的一些总结,如果有错误的地方,请大家多多指教,谢谢。另外,不支持Markdown,有些不方便。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11