我正在写 Michael J Laszlo 的书 ' Computation Geometry and Computer Graphics in C++ ' 。 下面是一个模板类原型(prototype):
template <class T> class ListNode : public Node {
T _val;
ListNode (T val);
friend class List<T>;
};
template <class T> ListNode <T>::ListNode(T val)
{_val=val;};
template <class T> class List{
private:
ListNode <T> *header;
ListNode <T> *win;
int _length;
public:
List(void);
~List(void);
T insert(T);
T append(T);
List * append(List*);
T prepend(T);
T remove(void);
void val(T); // overloaded function!
T val(void);// overloaded function!
T next(void);
T prev(void);
T first(void);
T last(void);
int length(void);
bool isFirst(void);
bool isLast(void);
bool isHead(void);
};
现在看看他定义List构造函数的方式:
// constructors and destructors
template <class T> list<T>:: List(void): _length(0)
{
header =new ListNode<T>(NULL);
win=header;
}
我的问题:
在 {...}
之外分配默认长度并在内部分配其余长度是怎么回事?这背后是否有某种逻辑推理?
因为例如在此之前,他几乎在 {...}
之外声明了所有内容,我认为这只是他的风格
最佳答案
What is up with the assigning a default length outside the parenthesis and the rest inside the curly braces?
这是非常普遍和可取的。该构造称为 initialization list .比如这个
template <class T> ListNode <T>::ListNode(T val)
{_val=val;};
可以重写为:
template <class T> ListNode <T>::ListNode(T val)
: _val(val) {};
使用此构造指示编译器对要复制的项目使用复制构造函数,而不是使用默认构造函数后跟赋值运算符。在分配基元的情况下,这无关紧要,但对于更复杂的类型,初始化列表可以为您节省一些 CPU 周期。
作者没有将 header
和 win
赋值放入初始化列表的原因是在重要的地方强制执行特定的初始化顺序。对 header
的赋值必须发生在对 win
的赋值之前。当您使用初始化列表时,分配的顺序不受列表中项目顺序的控制:相反,它由 relative order of declaration of the corresponding members in the class 控制。 .依赖它会让读者非常困惑,并且太脆弱而无法继续生产,因此作者正确地决定将这两个赋值移动到构造函数的主体中。
关于c++ - 是作者炫耀还是真实的做法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16738748/