类成员函数无法访问相同类的私有结构节点?

问题描述 投票:1回答:2

我正在做家庭作业,偶然发现了一个路障

我创建了一个看起来像这样的链接列表类

List.h
class List{
   struct Node{
       string data
       etc...
   }

   public:
       Node* lastNode(Node* root);
  List.cpp

  #include "List.h"

  List::Node* lastNode(Node* root){
      while(root && root->next){
          root = root->next;
      }
      return root;
  }

[当我尝试运行代码时,它在此上下文中显示“ struct List :: Node是私有的”(从List.cpp中lastNode的函数头开始)

我不知道是什么原因造成的。我知道私有字段只能由相同类的成员函数访问,但lastNode不是成员函数吗?

c++ class declaration public-method
2个回答
0
投票

类型List :: Node不能作为类List的公共成员访问。因此,您不能将其指定为公共成员函数的返回类型。

例如,您可以声明成员函数

auto lastNode(Node* root);

这里是演示程序。

#include <iostream>
#include <string>

class List
{
private:    
    struct Node
    {
        std::string data;
        Node *next;
    } *head = nullptr;      

public:
    auto find( const std::string &data ) const;
};

auto List::find( const std::string &data ) const
{
    Node *current = head;

    while ( current != nullptr && current->data != data ) current = current->next;

    return current;
}

int main() 
{
    List list;
    std::string s( "public List::Node" );

    auto node = list.find( s );

    if ( node == nullptr ) 
    {
        std::cout << s << " is not found\n";
    }

    return 0;
}

其输出为

public List::Node is not found

但是如果您允许列表的用户访问节点,那么也许您应该重新设计列表类。


0
投票
List::Node* lastNode(Node* root) { ... }

定义名为lastNodeglobal函数,返回一个List::Node*。您想将此定义为Listmember函数。为此,只需将名称lastNode限定为List::

List::Node *List::lastNode(Node *root) { ... } // * placement is more idiomatic this way

在函数名称上的第二个List::声明此函数“属于” List,因此其后的第二个Node不需要再次由List::限定。由于返回类型位于最后一个节点的List::之前,因此仍在全局范围内进行解释,因此您需要对其进行限定。除了历史惯性之外,我认为没有任何其他理由,因为历史惯性是编译器愚蠢到足以对此混淆的时候的停留。您还可以将返回类型放在限定的函数名称之后,在此可以省略限定符:

auto List::lastNode(Node *root) -> Node* { ... }

Godbolt

© www.soinside.com 2019 - 2024. All rights reserved.