【问题标题】:C++: Member is inaccessible - using friend function to allow one class to modify another class member dataC++:成员不可访问 - 使用友元函数允许一个类修改另一个类成员数据
【发布时间】:2019-11-18 00:56:25
【问题描述】:

好的,我已经到处寻找答案了。

我正在尝试建立一个系统,其中对象的私有成员只能通过单独类的两个成员函数进行修改。

这里是要修改的对象的表头内容,table.h:

#ifndef TABLE_H
#define TABLE_H

#include "party.h"

/*
Seats a party for their dining experience at the restaurant.
*/
class table
{
    friend void server::seatGuests(const table &, const party &);
    friend void server::cleanTable(const table &);

private:
    const unsigned int cap_; //guest capacity (shouldn't change)
    const unsigned int id_;  //table id (shouldn't change)
    mutable bool isTaken_;   //flag (changeable by friend functions)
    party *const group_;     //party seated at the table (starts off as null)

public:
    table::table(const unsigned int id, const unsigned int cap = 4); //ctor
    inline const unsigned int table::getCap() const { return cap_; }
    inline const unsigned int table::getId() const { return id_; }
    inline const bool table::isTaken() const { return isTaken_; }
    inline const party *const table::getParty() const { return group_; };
};

void server::seatGuests(const table &t, const party &p)
{
    t.isTaken_ = false;
}

#endif // TABLE_H

这里是 server.h:

class server : public employee
{
private:
public:
    explicit server::server();
    void server::seatGuests(const table &, const party &);
    void server::cleanTable(const table &);
};

...

我收到以下错误: member "table::isTaken_" (declared at line 17) is inaccessible

server.h 文件间接包含在 table.h 中,因为 party.h 包含 restaurant.h,其中包含 server.h。

我之前试过把它放在 table.h 中:

class server;
namespace server {
   void server::seatGuests(const table &, const party &);
   void server::cleanTable(const table &);
}

但这只是让我更头疼,因为编译器会吐出类似“类服务器没有成员'seatGuests'或'cleanTable'”之类的东西,我认为这是由于一些包含冲突。这个冲突是我在原始 server.h 文件中而不是在 table.h 文件中声明函数的原因。

话虽如此,我读过的诸如this one 之类的消息表明,友元函数的实现应该在其数据被修改的类中,这就是我所做的。

除此之外,编译器仍然认为成员数据不可访问。谁能看到我在这里做错了什么?

如果您希望我发布更多代码,请告诉我。

提前致谢。

编辑

对于延迟发布编译器输出表示歉意。请看下面:

> Executing task: clang++ -Wall -std=c++17 -stdlib=libc++ -o main.out /Users/ajm/Projects/restaurant/cpp/main/main.cpp -I/Users/ajm/Projects/restaurant/cpp/main/ -I/Users/ajm/Projects/restaurant/cpp/restaurant/ -I/Users/ajm/Projects/restaurant/cpp/people/ -I/Users/ajm/Projects/restaurant/cpp/people/workers/ -I/Users/ajm/Projects/restaurant/cpp/data/ --debug <

In file included from /Users/ajm/Projects/restaurant/cpp/main/main.cpp:1:
In file included from /Users/ajm/Projects/restaurant/cpp/main/simulation.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/restaurant/restaurant.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/restaurant/tablespace.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/restaurant/table.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/people/workers/server.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/people/workers/employee.h:5:
In file included from /Users/ajm/Projects/restaurant/cpp/main/../data/job.h:4:
/Users/ajm/Projects/restaurant/cpp/people/party.h:25:16: error: unknown type name 'restaurant'
    void start(restaurant &spot);
               ^
In file included from /Users/ajm/Projects/restaurant/cpp/main/main.cpp:1:
In file included from /Users/ajm/Projects/restaurant/cpp/main/simulation.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/restaurant/restaurant.h:4:
In file included from /Users/ajm/Projects/restaurant/cpp/restaurant/tablespace.h:4:
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:8:11: error: redefinition of 'server' as different kind of
      symbol
namespace server
          ^
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:7:7: note: previous definition is here
class server;
      ^
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:10:23: error: unknown type name 'table'
void seatGuests(const table &t, const party *const p);
                      ^
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:11:23: error: unknown type name 'table'
void cleanTable(const table &t);
                      ^
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:13:31: error: unknown type name 'table'
void server::seatGuests(const table &t, const party *const p)
                              ^
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:18:31: error: unknown type name 'table'
void server::cleanTable(const table &t)
                              ^
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:42:25: error: out-of-line declaration of 'seatGuests' does not
      match any declaration in 'server'
    friend void server::seatGuests(const table &t, const party *const p);
                        ^~~~~~~~~~
/Users/ajm/Projects/restaurant/cpp/restaurant/table.h:43:25: error: out-of-line declaration of 'cleanTable' does not
      match any declaration in 'server'
    friend void server::cleanTable(const table &t);
                        ^~~~~~~~~~
8 errors generated.
The terminal process terminated with exit code: 1

【问题讨论】:

  • 首先,类声明中的成员声明不应具有类限定符。修复此问题可能会修复一些错误消息。
  • 其次,我不认为你可以在命名空间范围内声明类成员函数(没有主体),就像你最后的摘录一样。
  • 如果你能发布一个给出错误的完整(精简)编译单元,我相信有人可以马上给你答案。
  • 哦,看起来你可能有循环包含
  • server 是否包含table?如果是这样,那么我认为这是你的问题

标签: c++ friend


【解决方案1】:

server::seatGuestsserver::cleanTable 的声明必须出现在 table 中的 friend 声明之前。 #include "server.h" 出现在 table 的声明之前,所以应该足够了吧?好吧,server 包括 tabletable 包括 server 所以我们有循环依赖。为了解决这个问题,table 应该包含server 并且server 应该转发声明table

// table.h

#include "party.h"

class table
{
    friend void server::seatGuests(const table &, const party &);
    friend void server::cleanTable(const table &);
};



// server.h

class table;
class party;

class server : public employee
{
public:
    explicit server();
    void seatGuests(const table &, const party &);
    void cleanTable(const table &);
};

循环依赖和友元声明对我来说似乎是糟糕的设计。您可能需要重新考虑设计,而不是使用前向声明来解决此问题。找到一种避免循环并避免友元声明的方法。 我的回答是解决方法,而不是解决方案。

【讨论】:

  • 谢谢。你对设计是绝对正确的。我还认为我需要退后一步,花更多时间阅读 C++,以确保我在成员类中使用适当的数据类型。
猜你喜欢
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
相关资源
最近更新 更多