【问题标题】:c++ access-specifier understandingc++ 访问说明符理解
【发布时间】:2018-01-30 16:27:39
【问题描述】:

我在一个线程中遇到了以下响应:

可以从派生类访问受保护的成员。私人的不能。

class Base {

private: 
  int MyPrivateInt;
protected: 
  int MyProtectedInt;
public:
  int MyPublicInt;
};

class Derived : Base
{
public:
  int foo1()  { return MyPrivateInt;} // Won't compile!
  int foo2()  { return MyProtectedInt;} // OK  
  int foo3()  { return MyPublicInt;} // OK
};

class Unrelated 
{
private:
  Base B;
public:
  int foo1()  { return B.MyPrivateInt;} // Won't compile!
  int foo2()  { return B.MyProtectedInt;} // Won't compile
  int foo3()  { return B.MyPublicInt;} // OK
};

...

1) 我的问题是: 我已阅读:“类派生列表命名一个或多个基类并具有以下形式:

类派生类:访问说明符基类

其中 access-specifier 是 public、protected 或 private 之一,而 base-class 是先前定义的类的名称。如果未使用访问说明符,则默认为私有。 " 和 "私有继承:从私有基类派生时,基类的公共和受保护成员成为派生类的私有成员。

"

所以...在我们的示例类 Derived : Base 等价于类 Derived : private Base 因为没有定义访问说明符,但代码按照作者所说的那样工作,所以我错过了什么?-我认为Derived 类访问说明符的基类是private,因此 Base 的公共和受保护成员对于 Derived 类应该是私有的并且不能被访问...谢谢!

【问题讨论】:

  • 你混淆了概念。访问说明符有两种不同的相关性。第一个与方法有关,即哪些类可以“看到”哪些基类方法。第二个与继承有关,这会影响诸如强制转换为基类/派生类等行为。
  • BaseDerived 的私​​有基类。一个类可以访问它自己的基(就像它自己的成员一样),无论它们是私有的、公共的还是受保护的。 (否则私有基类将是一件毫无用处的事情)。其他类无法通过Derived 对象访问Base,因为它是私有的。
  • 请注意,尽管private 是默认值,但“继承”通常指的是public 继承

标签: c++ access-specifier


【解决方案1】:

这是一个类似的想法。它不是应用于您可以访问的类的哪些成员,而是应用于您可以访问的基类。

class A
{
public:
    void f();
};



class B : public A
{
public:
    void g()
    {
        f(); // OK
        A *a = this; // OK
    }
};
class B2 : public B
{
public:
    void h()
    {
        f(); //OK
        A *a = this; // OK
    };
};
B b;
A& ba = b;


class C : protected A
{
public:
    void g()
    {
        f(); // OK, can access protected base
        A *a = this; // OK, can access protected base
    }
};
class C2 : public C
{
public:
    void h()
    {
        f(); // OK, can access protected base
        A *a = this; // OK, can access protected base
    };
};
C c;
c.f(); // Not OK, allthough A::f() is public, the inheritance is protected.
A& ca = c; // Not OK, inheritence is protected.




class D : private A
{
public:
    void g()
    {
        f(); // OK because A is a base of D
        A *a = this;
    }
};
class D2 : public D
{
public:
    void h()
    {
        f(); //Not OK, A is inherited with private in D
        A *a = this; //Not OK
    };
};
D d;
d.f(); // Not OK, allthough A::f() is public, the inheritance is private.
D& da = d; // Not OK, inheritence is private.

【讨论】:

    猜你喜欢
    • 2016-06-16
    • 2017-09-17
    • 1970-01-01
    • 2012-06-05
    • 2011-04-16
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2014-01-11
    相关资源
    最近更新 更多