构造函数/析构函数是否必须包含代码,或者功能是否足够?

时间:2013-03-01 02:18:54

标签: c++

所以,如果我有一个班级

class Transaction {

int no;
char dollar;

public:

    Transaction();
    ~Transaction();
}

在我的构造函数/析构函数

Transaction::Transaction {
    cout << "Entering constructor" << endl;
}

Transaction::~Transaction {
    cout << "Leaving program" << endl;
}

是否足以让我的构造函数和析构函数工作?它是否会将我班级中的数据成员设置为安全状态,即使我在构造函数中没有声明任何内容?

3 个答案:

答案 0 :(得分:5)

如果您提供的构造函数没有为所述子对象指定初始值设定项,则每个子对象都将默认初始化。

标准第8.5节规定:

  

如果没有为对象指定初始值设定项,则默认初始化该对象;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。 [注意:具有静态或线程存储持续时间的对象是零初始化的,请参见3.6.2。 - 结束说明]

那个

  

默认初始化 T类型的对象意味着:

     
      
  • 如果T是(可能是 cv-qualified )类类型,则调用T的默认构造函数(如果T没有,则初始化是错误的access default constructor);
  •   
  • 如果T是数组类型,则每个元素都是默认初始化的;
  •   
  • 否则,不执行初始化。
  •   
     

如果程序要求对const-quali类型T的对象进行默认初始化,T应为具有用户提供的默认构造函数的类类型。

有两种初始化子对象的方法:在 ctor-initializer-list 中,以及在成员声明中的 brace-or-equal-initializer 中(对于非-static成员后者是C ++ 11中的新成员。

实际上,这意味着当您不提供初始值设定项时,基本类型的变量(例如intchar)会保留先前在内存中保留的任何值。在大多数情况下,很难预测将会是什么价值,但你应该知道它可能是一个剩余的敏感数据,如密码。

在初始化静态存储持续时间的变量(例如命名空间范围内的对象及其成员)的情况下,标准进一步提供(相同部分):

  

在进行任何其他初始化之前,静态存储持续时间的每个对象在程序启动时都是零初始化的。

如果您没有定义构造函数,这与 value-initialization 期间发生的情况略有不同:

  

T类型的对象进行值初始化意味着:

     
      
  • 如果T是具有用户提供的构造函数的(可能是 cv-qualified )类类型,那么   调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);
  •   
  • 如果T是一个(可能是 cv-qualified )非联合类类型而没有用户提供的构造函数,那么该对象将被初始化为零,如果{{1}隐式声明的默认构造函数是非平凡的,调用构造函数。
  •   
  • 如果T是数组类型,则每个元素都是值初始化的;
  •   
  • 否则,该对象为零初始化。
  •   

但效果相同 - 原始成员设置为零,所有其他成员都调用了零参数构造函数。

nneonneo明确初始化所有成员的建议是好的,因为仅对静态存储持续时间的变量进行零初始化通常会导致难以发现的错误。但是使用大括号或等于初始化技术是完全可行的:

T

答案 1 :(得分:1)

您的类只有简单的数据成员,因此您甚至不需要(或者不想要)析构函数。

但是,您应该在构造函数中初始化数据成员:

Transaction::Transaction()
  : no(0), dollar('$') {
    cout << "Entering constructor" << endl;
}

否则,它们不会被初始化,并且可能包含随机值(如果不在构造函数中初始化它们,C ++不保证将原始非静态成员初始化为任何特定值)。如果你有指针成员,这可能会特别隐蔽。

答案 2 :(得分:0)

不,它没有代码。事实上,在大多数语言中,你可以将它排除在外,它将正确构建类。