在项目中碰到一个问题,在某个timer的构造函数中构造了一个对数据库的connection,但是在构造函数还没结束的时候connection就关闭了。后来才知道是因为临时变量的生存期的问题。大概的意思如下: 输出的结果为:
A :: default constructor
C :: default constructor
A :: constructor
A :: operator =
A :: destructor
B :: default constructor
B :: destructor
C :: destructor
A :: destructor
我们一行一行的分析,首先new了一个B的对象出来,B中有两个成员,分别是A类型和C类型,于是自动调用A类和C类的默认构造函数进行初始化,于是输出前两行。
然后在B的构造函数里面构造了一个A的临时对象,并且付给ba,于是输出第3,4行。但是这个临时变量的生存期只有一行,所以输出第5行。接着输出第6行。
最后delete掉这块空间,先调用B的析构,再调用成员的析构,于是输出7,8,9行。
这里的关键就是临时变量的生存期只有一行,这样就能解释在文章开头说的还没有出构造函数,connection就被关掉了,因为关掉了临时对象的连接,也就关掉了timer类中conn成员的连接。
----------------------------------------------------------------------------------------------
在刚才写的时候还碰到了这么一个问题,类C是我新加入的一个类,本来的代码是这样的: 这时候编译会产生错误,错误在第36行,说bc是一个不完全类型。
这是因为在第23行的声明是一个前向声明(forward declaration)。在类C的声明之后,定义之前,类C都是一个不完全类型(incomplete type)。即已知C是一个类型,但是不知道它包含哪些成员。
在创建类的对象之前,必须完整的定义类,不能仅仅声明类。这样,编译器才会为类的对象预定空间。同样的,在使用指针或者引用访问类成员之前,必须定义该类。例如: 在第30会报错,因为C这时候是一个不完全类型,而37行不会报错。
只有当类的定义在前面出现过,数据成员才能被指定为该类类型。如果该类型是不完全类型,那么数据成员只能是指向该类型的指针或者引用。
综合来说,就是:如果C是一个不完全类型,那么可以定义C类型的指针和引用(引用主要用于形参),如上边第37行。但是不能访问类C的成员,如第30行。
只有当类的定义体完成后才能定义类,因为一个类中不能含有自身类型的对象。然而,只要类名一出现就被认为是已经声明过,所以可以在类中定义自身类型的指针或者引用。比如:
项目中的错误:临时变量的生存期
最新推荐文章于 2022-12-04 18:14:00 发布