我的类有一个私有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<<
,但是我对以这种方式打破封装感到不舒服,并且想知道是否有人知道重载的方法{{ 1}}不使用operator<<
函数或将friend
公开?
答案 0 :(得分:2)
这是不可能的。您希望接受supportedMessageTypes
类型的参数,因此它必须是可见的。没有办法解决它。
此外,friend
功能在这里也不错;这是友谊的意图之一。
答案 1 :(得分:0)
尽管我付出了努力,但如果没有friend
关键字,我找不到办法。另一方面,这样做不打破封装,因为类中没有人可以使用该函数,因为它们无法访问类型查找中使用的类型。因此,你仍然完全被封装。
答案 2 :(得分:0)
我不同意你问题中的一些前提。特别是,当您说将operator<<
声明为friend
函数时会破坏封装。它打破封装的方式与您的类型的任何成员函数打破封装的方式完全相同。 operator<<
是您的类型的部分,可以访问private
部分,但这不是封装的破坏。请注意,在C ++中,不仅成员函数属于该类型的接口。谷歌的接口原则。
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;
}
};
该代码如何比原始代码更少封装?