访问控制和静态成员

时间:2018-06-25 22:30:05

标签: c++

我正在阅读有关静态成员函数的acces说明符,并以MSDN的示例为结尾:

// access_control.cpp  
class Base  
{  
 public:  
  int Print();             // Nonstatic member.  
   static int CountOf();    // Static member.  
};  


class Derived1 : private Base  
{  
};  

class Derived2 : public Derived1  
{  
  int ShowCount();    // Nonstatic member.  
};  

int Derived2::ShowCount()  
{  
  // Call static member function CountOf explicitly.  
  int cCount = Base::CountOf();     // OK.  

  // Call static member function CountOf using pointer.  
   cCount = this->CountOf();  // C2247. Conversion of  
                           //  Derived2 * to Base * not  
                           //  permitted.  
   return cCount;  
}  

所以它说这行是可以的,不是:

int cCount = Base::CountOf();     // OK.

这是错误消息:

error C2247: 'Base::CountOf' not accessible because 'Derived1' uses 'private' to inherit from 'Base'

那么错误真的存在吗,还是和我在编译时必须添加的某些Option有关?

Thx

1 个答案:

答案 0 :(得分:4)

在C ++ 17标准部分[class.access.base] / 3中,有一个与您的代码类似的示例:

  

私有基类的成员可能无法作为继承的成员名称访问,但可以直接访问。由于有关于指针转换(7.11)和显式转换(8.4)的规则,如果使用隐式转换,则从指向派生类的指针到指向不可访问的基类的指针的转换可能格式错误,但格式正确如果使用显式强制转换。例如,

class B {
public:
    int mi; // non-static member
    static int si; // static member
};
class D : private B {
};
class DD : public D {
    void f();
};

void DD::f() {
    mi = 3; // error: mi is private in D
    si = 3; // error: si is private in D
    ::B b;
    b.mi = 3; // OK (b.mi is different from this->mi)
    b.si = 3; // OK (b.si is different from this->si)
    ::B::si = 3; // OK
    ::B* bp1 = this; // error: B is a private base class
    ::B* bp2 = (::B*)this; // OK with cast
    bp2->mi = 3; // OK: access through a pointer to B.
}

您的代码与此不同之处在于您执行Base::CountOf()。这仍然是一个错误,因为在Derived2的上下文中检查了访问,并且对基类的私有成员没有访问权限。

但是::Base::CountOf()是正确的,因为然后在全局名称空间中检查访问。

您可以按照与标准示例类似的方式来修复示例的第二部分:(::Base *)this)->CountOf()