2011-04-06 217 views
4
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也可以吗?C++模板构造函数初始化

+1

'T data;'很好。你不希望使用'T data = 0',因为你不知道'T'是否是一个整型(如果我试图创建一个'Node '?) – user470379 2011-04-06 01:00:05

+0

或者也许T data = 0是一种合理的方式来强制假设T是一种数字类型? – Keith 2011-04-06 01:03:20

+1

@Keith:或者一个指针。或者有任何整数类型的隐式转换。或者有任何指针类型的隐式转换。不是一个非常强烈的主张。 – 2011-04-06 01:04:44

回答

6

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

另一种方式来做到这一点是:

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,则不需要默认构造函数。
+2

任何不将T数据参数设置为const T的原因? – Keith 2011-04-06 01:13:40

+0

@Keith:不,不是,我只是把它留在stonebird的代码中,因为没有一个令人信服的理由去改变它。 – 2011-04-06 02:36:39

+0

@Keith如果从右值初始化,'const T&'将阻止初始化器被移动到 – 2016-02-18 23:12:49

3

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

后者在C++ 03标准中描述的,第8.5节/ 5:

要值初始化类型T的对象是指:

  • 如果T是一个类类型(第9章)和用户声明的构造函数(12.1),那么调用T的默认构造函数(并且如果T没有可访问的默认构造函数,则初始化不合格);
  • 如果T是一个没有用户声明构造函数的非联合类类型,那么T中的每个非静态数据成员和基类组件都进行了值初始化;
  • 如果T是一个数组类型,则每个元素都进行了值初始化;
  • 否则,该目的是零初始化

要零初始化类型T的对象是指:

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

最后,接头一起,第8.5节/ 7:

其初始化为空集括号的一个目的,即(),应值初始化。