c++模板构造函数初始化

c++ template constructor initialization

本文关键字:初始化 构造函数 c++      更新时间:2023-10-16
template<class T>
class Node
{
    public:
    Node(Node<T>* next=NULL, T data=T()) : _next(next), _data(data)
    {
    } 
    Node<T>* _next;
    T _data;
};

我是c++模板新手。对于默认参数,T data = T()是标准的方法吗?也许T data = 0也可以?

这不是"构造函数初始化",这是一个默认参数。它允许调用者提供比函数更少的参数,未指定的参数将采用默认值。

另一种方法是:

template<class T>
class Node
{
    public:
    Node(Node<T>* next, T data) : m_next(next), m_data(data) {} 
    Node(Node<T>* next) : m_next(next), m_data() {} 
    Node(void) : m_next(NULL), m_data() {} 
    Node<T>* m_next;
    T m_data;
};

也允许使用少于两个参数,但调用不同的构造函数(几乎具有相同的行为)。使用单独的重载有很多优点:

  • 如果总是省略data参数,则不需要复制构造函数。
  • 不需要默认构造函数,如果总是提供data参数。

这与构造函数无关;你看到的是默认函数参数和值初始化的组合。

后者在c++ 03标准中有描述,§8.5/5:

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

  • 如果T是具有用户声明构造函数(12.1)的类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是病态的);
  • 如果T是没有用户声明构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;
  • 如果T是数组类型,则每个元素都进行值初始化;
  • 否则,对象为零初始化

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

  • 如果T是标量类型(3.9),则对象设置为0(零)转换为T的值;
  • 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;
  • 如果T是联合类型,则对象的第一个命名数据成员(89)为零初始化;
  • 如果T是数组类型,则每个元素为零初始化;
  • 如果T是引用类型,则不进行初始化。

最后,把它拼凑在一起,§8.5/7:

如果对象的初始化式是一组空圆括号,即(),则应该进行值初始化。