重载运算符<<对于私人枚举

发布于 2024-12-10 23:15:58 字数 851 浏览 0 评论 0 原文

我的类有一个私有enum,其成员用于索引字符串数组,其输出被写入输出流。

private:
    enum supportedMessageTypes(CRITICAL = 0, WARNING, INFORMATION);
    string messages[3];

//meanwhile, inside the constructor,
messages[3] = {"Critical error message", 
               "Warning message", 
               "Information message"};

由于我将在代码中大量使用枚举值,因此我希望能够重载 operator<< 来执行枚举值的查找,将其与数组中相应的字符串,并按以下方式返回:

cout << CRITICAL << ": " << messageText << std::endl;

我遇到的问题是 supportedMessageTypes 是私有的,而 operator<< 的重载应该作为非- 成员函数。我知道我可以定义一个 friend 函数来为我的类重载 operator<< ,但我只是不喜欢以这种方式破坏封装,并且想知道是否有人知道在不使用 friend 函数或不公开 supportedMessageTypes 的情况下重载 operator<< 的方法吗?

My class has a private enum whose members are being used to index an array of strings, the output of which is written to an output stream.

private:
    enum supportedMessageTypes(CRITICAL = 0, WARNING, INFORMATION);
    string messages[3];

//meanwhile, inside the constructor,
messages[3] = {"Critical error message", 
               "Warning message", 
               "Information message"};

Since I'm going to be using the enum values around my code a lot, I'd like to be able to overload operator<< to perform a lookup of the enum value, match it to the corresponding string in the array, and return that in the following manner:

cout << CRITICAL << ": " << messageText << std::endl;

The problem I have is that supportedMessageTypes is private while overloading of operator<< should be done as a non-member function. I know I can define a friend function that overloads operator<< for my class, but I'm simply not comfortable with breaking encapsulation in that way, and was wondering if anyone knew of a way to overload operator<< without using friend functions or making supportedMessageTypes public?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盗心人 2024-12-17 23:15:58

这是不可能的。您想要接受 supportedMessageTypes 类型的参数,因此它必须是可见的。没有办法解决这个问题。

另外,friend 函数在这里也不错;这是友谊的预期场景之一。

This isn't possible. You want to accept an argument of type supportedMessageTypes, so it must be visible. There's no way around it.

Also, a friend function wouldn't be bad here; this is one of the intented scenarios for friendship.

小嗲 2024-12-17 23:15:58

我不能同意你问题中的一些前提。特别是,当您说将 operator<< 声明为 friend 函数时,会破坏封装。它破坏封装的方式与您类型的任何成员函数破坏封装的方式完全相同。 运算符<<是类型的一部分,并且可以访问私有部分,但这并不破坏封装。请注意,在 C++ 中,不仅成员函数属于类型的接口。 Google 了解界面原理

class test {
   enum E { ok, nok };
   friend std::ostream& operator<<( std::ostream&, E );
};
std::ostream& operator<<( std::ostream& out, E e ) {
   if ( e == ok ) out << "ok";
   else out << "nok";
   return out;
}

请注意,您不会向任何人开放您的类,而仅向您的功能之一开放。如果您感到不安,请考虑一下生成相同代码的几乎等效的方式:

class test {
    enum E { ok, nok }
    friend std::ostream& operator<<( std::ostream& out, E e ) {
       if ( e == ok ) out << "ok";
       else out << "nok";
       return out;
    }
};

该代码的封装程度如何比原始代码更少

I cannot agree with some of the premises in your question. In particular, when you say that declaring the operator<< as a friend function breaks encapsulation. It breaks encapsulation in exactly the same way as any member function of your type breaks encapsulation. The operator<< is part of your type and has access to the private parts, but that is not a breakage of encapsulation. Note that in C++ not only member functions belong to the interface of the type. Google for interface principle.

class test {
   enum E { ok, nok };
   friend std::ostream& operator<<( std::ostream&, E );
};
std::ostream& operator<<( std::ostream& out, E e ) {
   if ( e == ok ) out << "ok";
   else out << "nok";
   return out;
}

Note that you are not opening your class to anyone, only to one of your functions. If you feel at unease, think of this almost equivalent way of generating the same code:

class test {
    enum E { ok, nok }
    friend std::ostream& operator<<( std::ostream& out, E e ) {
       if ( e == ok ) out << "ok";
       else out << "nok";
       return out;
    }
};

How is that code less encapsulated than your original code?

小糖芽 2024-12-17 23:15:58

http://ideone.com/gMTZ6

尽管我付出了努力,但如果没有friend 关键字。另一方面,这不会破坏封装,因为类之外的任何人都不能使用该函数,因为他们无法访问类型查找中使用的类型。因此,你仍然处于完全封装状态。

http://ideone.com/gMTZ6

Dispite my efforts, I couldn't find a way to do this without the friend keyword. On the other hand, this does not break encapsulation, as nobody outside of your class can use the function, since they cannot access the type being used in the type lookup. Ergo, you're still fully encapsulated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文