c++ - 策略继承和不可访问的 protected 成员

标签 c++ inheritance visibility protected policy

似乎无法访问模板策略类中的 protected 成员,即使类层次结构看起来是正确的也是如此。

例如,使用以下代码片段:

#include <iostream>
using namespace std;

template <class T>
class A {
  protected:
    T value;
    T getValue() { return value; }
  public:
    A(T value) { this->value = value; }
};

template <class T, template <class U> class A>
class B : protected A<T> {
  public:
    B() : A<T>(0) { /* Fake value */ }
    void print(A<T>& input) {
      cout << input.getValue() << endl;
    }
};

int main(int argc, char *argv[]) {
  B<int, A> b;
  A<int> a(42);
  b.print(a);
}

编译器(在 OS X 上为 clang,但 gcc 返回相同类型的错误)返回以下错误:

Untitled.cpp:18:21: error: 'getValue' is a protected member of 'A<int>'
      cout << input.getValue() << endl;
                ^
Untitled.cpp:25:5: note: in instantiation of member function 'B<int, A>::print' requested here
  b.print(a);
    ^
Untitled.cpp:8:7: note: can only access this member on an object of type 'B<int, A>'
    T getValue() { return value; }
      ^
1 error generated.

奇怪的是,编译器的最后一条注释是完全正确的,但自 b 以来就已经应用了。对象的类型是 'B<int, A>' .这是编译器错误还是代码中存在问题?

谢谢

最佳答案

您误解了 protected 访问的含义。

protected 成员可由派生类调用。但仅限于类本身包含的基础对象。

例如,如果我简化问题,使用:

class A {
protected:
    void getValue(){}
};

class B : protected A
{
public:
    void print(A& input)
    {
        input.getValue(); //Invallid
    }
};

getValue 不能在类本身内部的“A”对象以外的“A”对象上调用。 例如,这是有效的。

    void print()
    {
        getValue(); //Valid, calling the base class getValue()
    }

正如 Dan Nissenbaum 和 shakurov 所指出的。然而,这也是有效的:

void print(B& input)
{
    input.getValue();
}

这是因为我们明确地说输入是 B 的对象。编译器知道 B 的所有对象都具有对 getValue 的 protected 访问。在我们传递 A& 的情况下,该对象也可能是 C 的一种类型,它可以通过私有(private)访问从 A 派生。

关于c++ - 策略继承和不可访问的 protected 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15702146/

相关文章:

c++ - Linux 上的 SymbolicC++ 错误

c++ - protected 继承的实际用途是什么?

visibility - zingchart setseries数据可见性问题

iphone - iOS 相当于 Android View.GONE 可见性模式

javascript - Div 类型 ="hidden"+ 未隐藏

c++ - 你能从 gltf 文件中得到一个明确的骨架吗?

c++ - 多维数组作为具有任意边界的类成员

c# - 从 C++ 反序列化 protobuf 并在 C# 中重新序列化给出不同的输出

java - play2 Java EBean ORM : Inheritance and Generics

python - 我可以从 python 类中删除继承的嵌套类吗?