c++ - 依赖模板库的 protected 成员

标签 c++ templates

所以我通读了this问题,我理解模板中依赖名称的前提,以及有时如何必须使用 this-> 限定方法以确保编译器能够正确找到它,但是我遇到了一个场景我不知道如何解决。具体来说,当该方法所属的对象与 *this 属于同一类型,但它是不同的对象(可能属于不同的子类)时。例如:

#include <iostream>

template<class T>
class A
{
protected:
    virtual void foo() = 0;
};

template<class T>
class B : public A<T>
{
};

template<class T>
class C : public B<T>
{
protected:
    void foo() override
    {
        std::cout << "Hello, world" << std::endl;
    }
};

template<class T>
class D : public B<T>
{
protected:
    void foo() override
    {
        B<T> *b = new C<T>();
        b->foo(); // error: 'void A<T>::foo() [with T = int]' is protected
    }
public:
    void bar()
    {
        this->foo();
    }
};

int main()
{
  D<int> d;
  d.bar();
}

鉴于此继承层次结构,以及调用 b->foo(); 时的错误,调用该函数的正确方法是什么?据我了解,原则上它应该可供 D 中的代码访问,因为它是基类的 protected 成员,但它因模板系统而变得复杂。

最佳答案

您的问题与模板无关,如果您删除所有模板代码,则会出现相同的错误。

将成员声明为 protected意味着您只能从同一个(直接)类访问该成员;所以虽然 DC 可能都从 B 派生,但它们都是截然不同的类型,而不是 直接 B,因此DC 无法访问B 的另一个实例的 protected 成员>。

例如,使用您发布的一些代码来编写以下代码:

class D : public B
{
    public:
        void baz(D& d, B& b)
        {
            foo(); // ok: calls this->foo();
            d.foo(); // ok: type of `d` is `D`, same class
            b.foo(); // error: can't access protected member
        }
};

在您的代码中,将 B* b = new C(); 更改为 B* b = new B();D 类在尝试访问 protected 成员时仍会遇到相同的错误。如果将其更改为 D* b = new D();,则错误消失,因为 b 现在与其所在类的类型相同。

要解决此错误,您可以将 D 声明为 B 的 friend ,但这会引入其他需要考虑的问题,您还必须添加转发/ friend 您希望以这种方式访问​​ foo 的每个类的声明:

template < class T >
class D;

template <class T>
class B : public A<T>
{
    friend class D<T>;
};

但是,鉴于您发布的代码,人们倾向于将 bar 函数移出 D 并将其放入 B,那么您就不必处理前向声明,并且您的大部分代码保持不变:

template <class T>
class B : public A<T>
{
public:
    void bar()
    {
        this->foo();
    }
};

// Then in your D class, change the call from `foo` to `bar`

template <class T>
class D : public B<T>
{
protected:
    void foo() override
    {
        B<T> *b = new C<T>();
        b->bar();
    }
};

虽然这可能不适合您的特定情况,但最终您的问题基本上归结为需要 public 访问权限。

希望对您有所帮助。

关于c++ - 依赖模板库的 protected 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50672672/

相关文章:

C++ 多态性和模板类

templates - TYPO3 流体 : How is it possible to use conditions and variables outside of <f:section> to make the layout dynamic?

c++ - 标准布局 c++

c++ - masm 指令集资源

c++ - log4cplus:在 Logger::shutdown on Windows 上崩溃

c++ - 如何在 C++ 中检索基类的类型?

c++ - 查找C++内存泄漏

c++ - 对二维字符数组的行求和

c++ - 模板模板参数扣: three different compilers three different behaviors

python - Django:为每个实例注册模板过滤器/标签