允许C ++类访问其他类的某个“内部”成员,但不是私有的?

时间:2011-10-06 13:58:37

标签: c++ access-control

当编码在功能上紧密耦合的类,但是你想要一个简单的接口到世界其他地方时,如果我可以做这样的事情,它会很好:

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而不需要任何额外的功率。我意识到这个特殊的解决方案是不可能的,但是有什么常见的解决方案呢?

3 个答案:

答案 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的朋友可以创建它的实例,因此只有他们(或者他们传递对该键的引用的人)才能访问“受限制”的方法。

我非常喜欢这种方法来记录有限的访问权限。