What are access specifiers? Should I inherit with private, protected or public?
我对访问修饰符对于继承的意义感到困惑。涉及
什么是访问说明符?
对于C++中的类/结构/尤宁,有3个
public-声明为public的成员可以通过类的对象从类外部访问。
protected-声明为protected的成员可以从类外部访问,但只能在派生自该类的类中访问。
私有-这些成员只能从类内访问。不允许外部访问。
源代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class MyClass { public: int a; protected: int b; private: int c; }; int main() { MyClass obj; obj.a = 10; //Allowed obj.b = 20; //Not Allowed, gives compiler error obj.c = 30; //Not Allowed, gives compiler error } |
继承和访问说明符
C++中的继承可以是下列类型之一:
Private 继承Public 继承Protected 继承
以下是与以下各项相关的成员访问规则:
First and most important rule
Private members of a class are never accessible from anywhere except the members of the same class.
号公共继承:
All
Public members of the Base Class becomePublic Members of the derived class &
AllProtected members of the Base Class becomeProtected Members of the Derived Class.
号
也就是说,成员的访问权没有变化。我们之前讨论过的访问规则将进一步应用于这些成员。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Class Base { public: int a; protected: int b; private: int c; }; class Derived:public Base { void doSomething() { a = 10; //Allowed b = 20; //Allowed c = 30; //Not Allowed, Compiler Error } }; int main() { Derived obj; obj.a = 10; //Allowed obj.b = 20; //Not Allowed, Compiler Error obj.c = 30; //Not Allowed, Compiler Error } |
号私有继承:
All
Public members of the Base Class becomePrivate Members of the Derived class &
AllProtected members of the Base Class becomePrivate Members of the Derived Class.
号
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | Class Base { public: int a; protected: int b; private: int c; }; class Derived:private Base //Not mentioning private is OK because for classes it defaults to private { void doSomething() { a = 10; //Allowed b = 20; //Allowed c = 30; //Not Allowed, Compiler Error } }; class Derived2:public Derived { void doSomethingMore() { a = 10; //Not Allowed, Compiler Error, a is private member of Derived now b = 20; //Not Allowed, Compiler Error, b is private member of Derived now c = 30; //Not Allowed, Compiler Error } }; int main() { Derived obj; obj.a = 10; //Not Allowed, Compiler Error obj.b = 20; //Not Allowed, Compiler Error obj.c = 30; //Not Allowed, Compiler Error } |
受保护的继承:
All
Public members of the Base Class becomeProtected Members of the derived class &
AllProtected members of the Base Class becomeProtected Members of the Derived Class.
号
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | Class Base { public: int a; protected: int b; private: int c; }; class Derived:protected Base { void doSomething() { a = 10; //Allowed b = 20; //Allowed c = 30; //Not Allowed, Compiler Error } }; class Derived2:public Derived { void doSomethingMore() { a = 10; //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2 b = 20; //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2 c = 30; //Not Allowed, Compiler Error } }; int main() { Derived obj; obj.a = 10; //Not Allowed, Compiler Error obj.b = 20; //Not Allowed, Compiler Error obj.c = 30; //Not Allowed, Compiler Error } |
。
记住,同样的访问规则也适用于继承层次结构下的类和成员。
需要注意的要点:-访问规范按类而不是按对象
注意,访问规范C++在每个类的基础上工作,而不是按每个对象。一个很好的例子是,在复制构造函数或复制分配运算符函数中,可以访问所传递对象的所有成员。
-派生类只能访问其自己的基类的成员
请考虑以下代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Myclass { protected: int x; }; class derived : public Myclass { public: void f( Myclass& obj ) { obj.x = 5; } }; int main() { return 0; } |
它给出一个编译错误:
prog.cpp:4: error: ‘int Myclass::x’ is protected
号
因为派生类只能访问它自己的基类的成员。注意,这里传递的对象
您可以将一个函数或类声明为另一个类的
So do
friend s break Encapsulation?
号
不,他们没有,相反,他们增强了封装!
Scott Meyers在有效C++中的解释可能有助于理解何时使用它们——公共继承应该对IS-A关系进行建模,而私有继承应该用于"以"的形式实现——因此,您不必坚持超类的接口,而只是重用实现。