【问题标题】:std::ostream : class is inaccesible [C++]std::ostream : 类不可访问 [C++]
【发布时间】:2017-12-03 02:50:25
【问题描述】:

我在实现中遇到了这个错误:

struct bookdatabase::Bookdatabase::Book

类“bookdatabase::BookDatabase::Book”不可访问

以下解决方案均未解决我的问题:

Here's Visual Studio 在 .cpp 文件中存在问题的图片。

Here's头文件中声明的图片。


数据库.h

#include <string>
#include <vector>


#ifndef BOOKDATABASE_H
#define BOOKDATABASE_H

namespace bookdatabase {
    class BookDatabase {
    private:
        struct Book {
        private:
            std::string authorFirstName, authorLastName, authorFullName, bookTitle, pubDate;
        public:
            Book(const std::string &authFirst, const std::string &authLast, const std::string &title, const std::string &date);
            std::string getAuthor() const;
            std::string getBookTitle() const;
            std::string getPubDate() const;
            bool operator < (const Book &rhs) const;
            friend std::ostream& operator << (std::ostream& out, const bookdatabase::BookDatabase::Book& book);
        };
        void sortBooks();
        std::vector<Book>::iterator search(const std::string &title);
    public:
        BookDatabase();
        void printBookList();
        std::vector<Book> getDatabase() const;
        void removeBook(const std::string &title);

        void addBook(const std::string &authFirst, const std::string &authLast, const std::string &title, const std::string &date);
    private:
        std::vector<Book> database;
    };
}

#endif // BOOKDATABASE_H


数据库.cpp

std::ostream & bookdatabase::operator<<(std::ostream & out, const bookdatabase::BookDatabase::Book & book) {
    out << authorFullName << ". " << bookTitle << ". " << pubDate;
    return out;
}


我遇到这个问题是因为Book 类是嵌套类吗?

【问题讨论】:

  • “我有这个问题是因为Book 类是一个嵌套类吗?” 不,你有这个问题是因为它是一个private 嵌套类。
  • @user0042 谢谢。我的理解是,如果重载运算符是类的朋友,它将可以访问其私有成员。如果课程是私人的,这不适用吗?让操作符成为 Database 类的朋友而不是访问 Book 类有意义吗?

标签: c++ c++11 inner-classes friend ostream


【解决方案1】:

好吧,我似乎在这里发现了两件事,这可能是您遇到的问题,其中一件可能是 Visual Studio 中的错误。

1。首先,不是bug的东西

user0042,在他对您的帖子的回复中是对的,operator&lt;&lt;struct Book 中被声明为friend 导致operator&lt;&lt; 只能访问Book 的私有成员。但它不能访问Book 本身,因为Book 是封闭BookDatabase 类的私有成员。因此,您必须将朋友声明移到Book 之外和BookDatabase 中。

完成此操作后,operator&lt;&lt; 现在可以访问 BookDatabase 的私有数据成员 Book。但是请注意,这并不授予operator&lt;&lt; 访问Book 本身的私有数据成员的权限,即authorFirstName, authorLastName, authorFullName, bookTitle, pubDate

2A。现在对于(我认为的)VS2017 范围运算符错误

假设您已将朋友声明移至BookDatabase,您仍然需要以特定方式定义实现。以下两段代码应该是在Database.cpp 文件中定义函数的等效方法,但其中一个在 VS2017 15.4.5 中不起作用

没关系

namespace bookdatabase {
    ostream& operator<<(ostream& out, const bookdatabase::BookDatabase::Book& book) {
    }
}  // OK

但不行

ostream& bookdatabase::operator<<(ostream& out, const bookdatabase::BookDatabase::Book& book) {
}  // Visual Studio cannot access book

Visual Studio 的 :: 运算符似乎存在问题,无法获取函数的 friend 属性。

所以回答你的问题:如果你想让你的

2B。其实我写了一个简单的测试程序来展示VS2017的friend::的bug

namespace my_namespace {
    class Test {
    private:
        struct Nested {};
    public:
        friend void func(Test::Nested&);
    };
    void func(Test::Nested&);
}

// DOES NOT COMPILE in VS2017 15.4.5, OK in GCC 6.3 and Clang 3.8.0
// VS2017 says Nested is inaccessible
void my_namespace::func(my_namespace::Test::Nested&) {
} 

但是使用namespace 和括号可以工作

namespace my_namespace {
    class Test {
    private:
        struct Nested {};
    public:
        friend void func(Test::Nested&);
    };
    void func(Test::Nested&);
}

// changed to namespace + brackets, 
// COMPILES in VS2017 15.4.5, GCC 6.3 and Clang 3.8.0
namespace my_namespace {
    void func(my_namespace::Test::Nested&) {
    } 
}

有人可以独立验证吗?

我还发了bug report on the Microsoft Developer Community

【讨论】:

  • 我将 operator&lt;&lt; 友元函数移至 Database 类并删除了 bookdatabase 命名空间范围解析运算符,选择将 operator&lt;&lt; 实现放在命名空间块中(如您的帖子中所示)。不幸的是,我仍然收到嵌套Book 类不可访问的错误。我认为唯一的解决方案可能是将嵌套的Book 类公开。
  • 奇怪,你的编译好了吗?我的编译很好。你能告诉我哪里出了问题吗?如果您尝试从函数体内访问 Book 的数据成员,那么您不能这样做,因为 operator&lt;&lt; 不是 Book 结构的朋友。
【解决方案2】:

对于大多数运算符

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-31
    • 2021-04-25
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2017-05-31
    相关资源
    最近更新 更多