为啥我不能在初始化列表中使用箭头运算符?
Posted
技术标签:
【中文标题】为啥我不能在初始化列表中使用箭头运算符?【英文标题】:Why can't I use arrow operator in initialization list?为什么我不能在初始化列表中使用箭头运算符? 【发布时间】:2017-01-26 04:53:52 【问题描述】:我是 C++ 的初学者。最近在练习写一个链表的时候,我尝试使用我的类构造函数的初始化列表来给head->next赋值NULL。
在类构造器中,它警告我的箭头运算符“期望一个'('或''”。为什么会出现这样的错误?(我知道我可以在块中初始化类成员,但为什么不能' t 我用这个指针来做这个?) 谢谢!
这是我的链表头文件:
链表.h
#include <iostream>
using namespace std;
struct node
int val;
node *next;
;
class linkedlist
private:
node *head;
int listlen;
public:
linkedlist();
void insert(node*, int);
void del(node*);
void reverse(node*);
void traverse(node*);
int random();
~linkedlist();
;
这是我的类构造函数:
linkedlist.cpp
#include "linkedlist.h"
#include <iostream>
linkedlist::linkedlist() :listlen(0), head->next(NULL)
【问题讨论】:
两个问题:首先head
没有初始化。其次,初始化列表中不能有表达式。
@Someprogrammerdude 常量表达式呢?
为什么?因为这就是语言的设计方式。 (大概初始化列表一直用于初始化对象本身,而不是它的成员可能指向的其他对象。)
@JoelCornett 可以将非常量表达式作为 initializer,作为用于初始化成员变量的值。但是对于要初始化的变量,不允许有通用表达式(如head->next
)。
@Someprogrammerdude 哦,你知道我完全看错了构造函数。我明白了。
【参考方案1】:
通常,您只能将成员本身作为初始化列表的一部分进行初始化。如果这是您在这里唯一的问题,那么您可以将指向 NULL
的 next-pointer 初始化为 ctor 主体的一部分。但是,您的成员变量 head
本身就是一个指针,并且当前没有指向任何地方,所以我怀疑您实际上想将 head
本身设置为 NULL
(或者 nullptr
如果您使用的是 c++11 或稍后):
linkedlist::linkedlist() :listlen(0), head(NULL)
您还可以考虑在您的struct node
中另外添加一个ctor,以便在初始化时将next
初始化为NULL
。
自从你说你是新人以来,我认为值得指出的其他一些事情:
请注意,初始化列表不是按照它们在 ctor 中写入的顺序运行的,而是按照成员在类主体中定义的顺序运行的。在您的情况下,此 listlen
实际上仅在 head
初始化后才初始化为 0。这对于您的代码来说并不重要,但如果成员的初始化更复杂并且具有依赖关系,则可能很重要。就个人而言,我建议始终保持初始化列表的顺序与成员定义的顺序相匹配。如果不是这种情况,某些编译器也有警告标志。
您是否考虑过使用标准库中的数据结构,而不是实现自己的链表?查看 cppreference.com 以获取有关它的大量重要信息。特别是,根据您的用例检查“列表”、“向量”或“双端队列”。
【讨论】:
感谢您的意见!我会记住初始化顺序。并且,对于数据结构本身,是否需要将 head 指针初始化为 NULL 和 head->next 为 NULL ? 除非你这样做,否则它们将有一个未定义的值,这对于指针意味着它们是无效的,如果你试图取消引用它们,可能会导致你进入 SEGV。出于这个原因,在大多数情况下,您希望显式地初始化它们,以便稍后您可以对这些值进行推理。我说“在大多数情况下”,因为有时您可能会有不同的状态,让我们保证您不会访问这些成员,直到它们被初始化。以上是关于为啥我不能在初始化列表中使用箭头运算符?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能访问派生构造函数的成员初始化列表中继承的受保护字段?
为啥不能在派生类的构造函数初始化列表中初始化基类的数据成员?
为啥 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,in