c++;模板构造函数初始化 模板 类节点 { 公众: 节点(Node*next=NULL,T data=T()):_next(next),_data(data) { } 节点*\u下一步; T_数据; }; 我是C++模板的新手。对于默认参数,T data=T()?也许T data=0也可以

c++;模板构造函数初始化 模板 类节点 { 公众: 节点(Node*next=NULL,T data=T()):_next(next),_data(data) { } 节点*\u下一步; T_数据; }; 我是C++模板的新手。对于默认参数,T data=T()?也许T data=0也可以,c++,C++,这不是“构造函数初始化”,而是默认参数。它允许调用方提供比函数更少的参数,未指定的参数将采用默认值 另一种方法是: template<class T> class Node { public: Node(Node<T>* next=NULL, T data=T()) : _next(next), _data(data) { } Node<T>* _next; T _data; }; 模板 类节点 { 公众:

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

另一种方法是:

template<class T>
class Node
{
    public:
    Node(Node<T>* next=NULL, T data=T()) : _next(next), _data(data)
    {
    } 
    Node<T>* _next;
    T _data;
};
模板
类节点
{
公众:
Node(Node*next,T data):m_next(next),m_data(data){}
Node(Node*next):m_next(next),m_data(){}
Node(void):m_next(NULL),m_data(){}
Node*m_next;
T m_数据;
};
其中也允许使用少于两个参数,但调用不同的构造函数(具有几乎相同的行为)

使用单独的重载有许多优点:

  • 如果总是忽略
    数据
    参数,则不需要复制构造函数
  • 如果始终提供
    数据
    参数,则不需要默认构造函数

这实际上与构造函数无关;您看到的是默认函数参数和值初始化的组合

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

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

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

将T类型的对象初始化为零意味着:

  • 如果T是标量类型(3.9),则将对象设置为0(零)的值,并转换为T
  • 如果T是非并集类类型,则每个非静态数据成员和每个基类子对象初始化为零
  • 如果T是联合类型,则对象的第一个命名数据member89)初始化为零
  • 如果T是数组类型,则每个元素初始化为零
  • 如果T是引用类型,则不执行初始化
最后,拼凑起来,§8.5/7:

初始值设定项为空括号集的对象,即(),应进行值初始化


T数据很好。您不想使用
t data=0
因为您不知道
t
是否为整数类型(如果我尝试创建一个
节点
?),或者t data=0可能是一种合理的方法,可以强制假设t为数字类型?@Keith:或指针。或从任何整数类型进行隐式转换。或具有来自任何指针类型的隐式转换。这不是一个很有力的论断。事实上,这是不正确的。它可以是指针类型,也可以是任何使用指针构造的对象,例如
string
。有没有理由不将
T data
参数设置为
const T&
?@Keith:不,没有,我只是把它保留在stonebird的代码中,因为没有强制理由更改它。@Keith如果从右值初始化,
const T&
将阻止移动初始值设定项in@M.M你需要
m_data(move(data))
,否则你只是为了制作一个额外的拷贝而移动--
const T&
,正如基思建议的那样,只会导致一个拷贝的一致性
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;
};