当编码在功能上紧密耦合的类,但是你想要一个简单的接口到世界其他地方时,如果我可以做这样的事情,它会很好:
class log
{
private:
log_context& cont;
public:
create_log_section(std::string name)
{
cont.create_log_section(name);// this is fine! It's "internal"
cont.this_is_private(); // doesn't compile. Don't want anyone touching my privates!
}
};
class log_context
{
internal:
void create_log_section(std::string name);
private:
void this_is_private();
internal friend log; // Wow, possible?
}
现在,这将允许日志访问上下文的相关部分,而不是私有部分。程序的其余部分应使用日志添加任何上下文。它也可以在日志之间传递强类型log_contexts
而不需要任何额外的功率。我意识到这个特殊的解决方案是不可能的,但是有什么常见的解决方案呢?
答案 0 :(得分:7)
您可以使用内部类来执行此操作
class log_context
{
class internal
{
friend log;
static void create_log_section( log_context & context, std::string name)
{
context.create_log_section( name );
}
}
private:
void create_log_section(std::string name);
void this_is_private();
}
class log
{
private:
log_context& cont;
public:
void create_log_section(std::string name)
{
log_context::internal::create_log_section( cont, name );// this is fine! It's "internal"
}
};
内部仅作为私有静态功能,只有其朋友可以访问它
答案 1 :(得分:4)
友谊不会跨越继承边界。如果log_context
要继承某些log_context_base
,并且this_is_private
属于log_context_base
,则log_context
成为log
的朋友则不会允许log
访问this_is_private
。
class log_context_base
{
protected:
void this_is_private();
}
class log_context : protected log_context_base
{
internal:
void create_log_section(std::string name);
friend log;
}
请注意,我在这里使用了保护继承,因为我不希望使用log_context_base*
访问log_context。
通过这种方式,您可以获得所需内容,而无需在语言中添加新关键字;)
答案 2 :(得分:0)
一般的解决方案是建立一个full
朋友,因为它在你的控制之下,只要确保它只触及它应该接触到的东西。
我之前提出的另一个解决方案是使用Key
。
class Key { friend class log; Key() {} ~Key() };
class log_context {
public:
void create_log_section(std::string name, Key const&);
};
只有Key的朋友可以创建它的实例,因此只有他们(或者他们传递对该键的引用的人)才能访问“受限制”的方法。
我非常喜欢这种方法来记录有限的访问权限。