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++模板构造函数初始化
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++模板构造函数初始化
这不是“构造函数初始化”,这是一个默认参数。它允许调用者提供比函数少的参数,未指定的参数将采用默认值。
另一种方式来做到这一点是:
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
,则不需要默认构造函数。任何不将T数据参数设置为const T的原因? – Keith 2011-04-06 01:13:40
@Keith:不,不是,我只是把它留在stonebird的代码中,因为没有一个令人信服的理由去改变它。 – 2011-04-06 02:36:39
@Keith如果从右值初始化,'const T&'将阻止初始化器被移动到 – 2016-02-18 23:12:49
这真的和构造函数无关;你看到的是默认函数参数和值初始化的组合。
后者在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:
其初始化为空集括号的一个目的,即(),应值初始化。
'T data;'很好。你不希望使用'T data = 0',因为你不知道'T'是否是一个整型(如果我试图创建一个'Node'?) –
user470379
2011-04-06 01:00:05
或者也许T data = 0是一种合理的方式来强制假设T是一种数字类型? – Keith 2011-04-06 01:03:20
@Keith:或者一个指针。或者有任何整数类型的隐式转换。或者有任何指针类型的隐式转换。不是一个非常强烈的主张。 – 2011-04-06 01:04:44