【问题标题】:Can't access members of a Template base class within a derived template class无法在派生模板类中访问模板基类的成员
【发布时间】:2012-09-12 22:34:00
【问题描述】:

我有一个模板基类。让我们说吧。

template<class KeyF>
class Base 
{
  private:
   int member1;
   char member2;
   ....
};

我从上面的类派生了另一个类。

template<class KeyF>
class Derived : public Base<KeyF>
{
  public:
  void func1() {
    <accessing member1/member2>
  }

  ....
};

以上代码不能在 gcc 中编译。说 member1 不是 Derived 的成员。但是它已经派生自一个基类,那为什么不能访问它的成员呢?

【问题讨论】:

  • member1member2 应该声明为 protected 或者更好的是,您应该为它们提供受保护的 getter/setter。
  • xaizek 是正确的,但也请参阅 this question - 您需要使用 this-&gt; 限定这些访问。

标签: c++ class templates gcc compiler-errors


【解决方案1】:

我认为解决该问题需要进行两项更改:

  1. 在基类中,将成员定义为“受保护”而不是“私有”,以便在派生类中访问。

  2. 在派生类中,在受保护成员之前添加基类名称。在这种情况下,它应该看起来像“Base::member1”。

在我的例子中使用 C++17 标准,问题得到了解决。希望这会有所帮助。感谢 Kerrek SB 提供的信息。

【讨论】:

  • 问题回到了 c++20。
【解决方案2】:

Base 的成员是private。您无法访问该课程之外的课程private membersfriend 除外)。将它们设为protected,或设为protected getters

【讨论】:

  • 公共吸气剂是一个糟糕的建议,因为它破坏了封装。
  • @DavidRodríguez-dribeas getters 破坏了封装?我不说 setter,我说 getter。
  • @ForEveR:是的,他们有。它们将您的类型的实现细节泄漏给所有其他代码。为了帮助论证,我必须说我通常使用两个术语:属性和吸气剂来表示不同的事物。 “属性”是域中对象的特征,而“getter”是提供对内部结构的访问的函数(即向量中的“size()”是类型的属性,可能会或不会检索成员)。属性不会破坏封装,因为它们是对象的特征,但是 getter(不是属性,而是返回内部的函数)会破坏封装。 [...]
  • [...] 如果成员受保护,则它是基类型和派生类型之间的内部接口的详细信息,而不是域中的公共属性。将其公开会增加其余代码的耦合度。您正在向所有其他代码泄露您的实现细节。
【解决方案3】:

您需要在基成员名称前加上this-&gt;Base&lt;KeyF&gt;::,或在类中添加using 声明以取消隐藏它们。它们的名称是依赖名称,它们是隐藏的。

【讨论】:

  • 它们也是private,这使得它们在派生类中无法访问。
  • @DCoder:这是一个单独的问题,不过……有单独的错误消息?!
【解决方案4】:

您是否尝试过受保护?自从我深入 C++ 以来,已经有点...

【讨论】:

    猜你喜欢
    • 2018-09-18
    • 2014-03-13
    • 2016-02-02
    相关资源
    最近更新 更多