将自身转换为派生类后可以访问c ++基本私有方法吗?

时间:2018-09-20 22:12:37

标签: c++ private crtp

当我使用CRTP(奇怪地重复使用模板模式)时发现了这一点。

template <typename T>
class Base {
private:
    void f() {
        //when T has its own f(), it calls that
        //when T doesn't have, it calls itself, which is invoked recursively
        //but i expect the compiler to complain that f() is private when T doesn't have its own f()
        static_cast<T*>(this)->f();
    }

public:
    void g() {
        f();
    }
};

class Derived : public Base<Derived> {};

我以为我了解publicprotectedprivate,但是对于这种情况,看来我是错的。任何解释表示赞赏!

1 个答案:

答案 0 :(得分:1)

这仅在阴影声明为public时有效。参见this example

class Derived : public Base<Derived> {
private:
    void f() { }
};

void x(Derived* d) {
    d->g();
}

您得到:

<source>: In instantiation of 'void Base<T>::f() [with T = Derived]':
<source>:13:9:   required from 'void Base<T>::g() [with T = Derived]'
<source>:23:10:   required from here
<source>:8:9: error: 'void Derived::f()' is private within this context
         static_cast<T*>(this)->f();
         ^~~~~~~~~~~
<source>:19:10: note: declared private here
     void f() { }
          ^

如果该函数未在Derived中隐藏,则该调用与必须合法的this->Base<Derived>::f()相同,因为Base是唯一可以访问它的类。 / p>

您的困惑还可能是由于访问了一个看似不同的对象而引起的。请记住,访问修饰符根据作用域而不是实例来限制访问。在Base中声明的任何方法都可以触摸任何 Base实例的私有成员,而不仅仅是this的私有成员。