【问题标题】:Parent access child private/protected父访问子私有/受保护
【发布时间】:2016-06-18 15:19:40
【问题描述】:

是否有可能以某种方式允许父母访问受儿童保护的成员?

template <class T>
class B {
public :
    void print()
    {
        cout << T::a << T::b << endl;
    }
};

class C : public B<C>
{
protected :
    static int a;
    static int b;
public :
    C() {
        print();
    }
};

这对我在没有多态性(虚拟)的情况下继承多个对象很有用。有什么建议吗??

编辑:

我找到以下建议的两个解决方案::

  • 将 B 设为好友类,
  • CRTP

还有几点需要考虑,在使用 CRTP 时,请确保您使用内联,否则它不会使其更快(但可能会发生代码膨胀)。不要忘记使 B 构造函数受保护(在静态派生数据访问的情况下)。

CRTP 也可用于不将静态常量数据(虚拟静态常量)从基类转移到派生类

现代编译器使用一个称为去虚拟化的概念,我认为它现在在大多数编译器中。

【问题讨论】:

  • 制作B的C friend
  • CRTP 正好相反!
  • 我知道会这样说,但关键是为什么我只提到受保护的数据。根据设计,这不是一个有效的解决方案,因为我无法将所有派生类添加为基类的朋友。
  • 为什么朋友不是一个选项?请注意,您不需要为每个子类在B 中添加friend class C,但您只需在每个子类中添加一行friend class B
  • 因为我是唯一一个提出问题的人,所以我认为您的评论是针对我的。不,我问这个问题并不奇怪,我真的不明白你的评论。当然也有用例,看看CRTP,它被广泛使用。我不明白您为什么要在要公开访问这些功能时坚持对它们进行保护。但是,如果你想这样做,让班级成为朋友是不二之选。

标签: c++ templates polymorphism


【解决方案1】:

这对我在没有多态性(虚拟)的情况下继承多个对象很有用。

这是一种众所周知的模式,又名静态多态

CRTP 通常使用static_cast&lt;T*&gt;(this) 来引用派生类函数:

template <class T>
class B {
public :
    void print()
    {
        cout << static_cast<T*>(this)->a << static_cast<T*>(this)->b << endl;
             // ^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^
    }
};

我需要以某种方式允许父母访问受儿童保护的数据,这可能吗?

当然可以。这些必须是Tpublic 成员,或者您需要使B&lt;T&gt; 成为friendT 类:

class C : public B<C>
{
     friend class B<C>;
  // ^^^^^^^^^^^^^^^^^^
protected :
    static int a;
    static int b;
public :
    C() {
        print();
    }
}; 

Live Demo


friend 声明仍然保留class C 的封装,同时开放对class B&lt;T&gt; 中声明的特定接口的访问。

【讨论】:

  • 我想答案是我们不能,公共数据只能通过这个指针直接访问,静态的和非静态的。
  • @KartikV static 与否无关紧要。真正重要的是范围。
  • 嗨,这很重要,静态成员不会出现这种情况。不幸的是,它应该是公开的。
  • @KartikV 我不明白你的意思。 Both variantsfriend 合作。没有规定废除它。如果您需要它,请使用它。 friend 仍然有助于将所有内容封装,除非您需要例外。
猜你喜欢
  • 2012-06-22
  • 2018-07-16
  • 2014-12-06
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 2016-04-03
  • 2016-07-15
相关资源
最近更新 更多