C++:无法访问节点值

C++ : cannot access node value

本文关键字:节点 访问 C++      更新时间:2023-10-16

我正在尝试使用取消引用运算符打印新创建的节点。

我的主要职能

int main ()
{
Insert(3);
return 0;
}

插入(( 函数

void Insert(int data)
{
Node *temp = new Node ;
temp -> data = data ;
temp -> next = NULL ;
cout << *temp ;
}

我的错误 :

tp.cpp: In function ‘void Insert(int)’:
tp.cpp:27:10: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘Node’)
cout << *temp ;

问题:C++只为其基本类型提供运算符,对于用户定义的类型,我们必须编写自己的运算符。错误no match for ‘operator<<’指出编译器找不到针对语句的<<运算符cout << *temp ;

可能的解决方案:

  1. 就像@user4581301说的,你可以为你的类型Node编写自己的<<运算符。

  2. 还可以将cout << *temp ;语句替换为cout << temp->data ;cout << (*temp).data ;,因为 temp 是指向结构的指针。 您可以使用data之前访问->它,也可以在使用*运算符取消引用它之后使用.访问它。

任何运算符基本上都是一个函数。 例如,对于您的类 Rational,一个加法运算符重载运算符 + 可以表示为 Member 函数:

class Rational
{
private:
...
...
public:
...
//Implicit arg "this" is Left Hand operand.
//Explicitly stated arg objRational is Right Hand operand.
Rational operator+(const Rational& objRational) const {...};
...
};

请注意,此处const参数是为了确保我们不会意外修改操作数本身,并且函数将自身标记为const以确保我们不会修改对象this。Arg 是通过 ref 传递的,因为如果我们不确定地修改它,则无需复制,也不会对 ref 造成伤害。

以上在技术上是一个函数,所以你可以做一些类似的事情

Rational r1(3, 4), r2(22, 7);
Rational r3 = r1.operator+(r2); //Really possible! Try it!

然后,它只是添加到语法C++语法中的语法糖,以允许与

Rational r3 = r1 + r2;


你写的

cout << *temp ;

其中,(*temp)的类型是 Node,coutostream类的对象。

因此,编译器现在正在寻找一个重载运算符,其中左操作数和ostream对象,右操作数和Node对象。

所以,它和写作一样好,在类流本身的某个地方,

class ostream : ...
{
...
...
//Here, the only one explicit arg is Node, 
//which is Right Hand side operand.
//Since it is a member operator, 
//implicit arg "this" will be, by default, the LH operand.
public ostream& oprtator<<(const Node& objNode){...}
...
}

但是,我们没有这种可能性,因为我们一开始就没有编写类 ostream。当它被写入时,你的节点不存在!此外,它可能需要访问 objNode 的私有成员,这对于不是 Node 类成员的函数来说是不允许的。

如果我们尝试将其作为类 Node 的成员,它可以访问 Node 的私有成员。但是现在operator<<的左操作数将需要是 Node,这会破坏整个目的。

所以,我们所做的是让它成为一个朋友功能。

class Node
{
...
...
public:
...
//Since this is NOT a member, bot LH and RH operand need to be stated explicitelty
friend ostream& operator<< (ostream& out, const Node& objNode) { out << node.data; return out; }
...
};

这将创建一个operator<<,该将操作数左操作数ostream,右操作数和node,并且可以访问 Node 的私人成员,因为它是朋友。(^_^)

为什么要接受并返回ostream 对象的引用?

因为,当您尝试链接调用时,您需要串行写入相同的对象。

考虑一个语句:cout << "First: " << objNode1 << ", Second: " << objNode2;

它将被评估为

(
(
(
cout << "First: " //Innermost call
) << objNode1       
) << ", Second: " 
)<< objNode2;

从内到外,对于每个调用,我们需要将ostream对象传递给具有所有先前插入的重载运算符,因此内部调用需要返回对要返回的ostream的修改(插入后(对象的引用。

希望对您有所帮助;快乐编码:)