[英]What are access specifiers? Should I inherit with private, protected or public?
我對訪問修飾符在繼承方面的含義感到困惑。 涉及private
, protected
和public
關鍵字的繼承之間有什么區別?
C ++中的class / struct / Union有3個access specifiers
。 這些訪問說明符定義了如何訪問類的成員。 當然,類的任何成員都可以在該類中訪問(在同一類的任何成員函數內)。 繼續介紹訪問說明符的類型,它們是:
公共 -可以通過類的對象從類外部訪問聲明為“公共”的成員。
受保護的 -聲明為受保護的成員只能從類BUT外部訪問, 但只能從該類派生。
私人 -這些成員只能在班級內部訪問。 不允許外部訪問。
源代碼示例:
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
繼承 以下是與每個規則有關的成員訪問規則:
第一條也是最重要的規則除同一個類的成員外,從任何地方都無法訪問該類的
Private
成員。
基類的所有
Public
成員將成為派生類的Public
成員,並且
基本類的所有Protected
成員都將成為派生類的Protected
成員。
即,成員的訪問權限沒有變化。 我們之前討論的訪問規則將進一步應用於這些成員。
代碼示例:
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
}
所有基礎類的
Public
成員都將成為派生類的Private
成員,
基本類的所有Protected
成員都將成為派生類的Private
成員。
一個代碼示例:
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
}
所有基類的
Public
成員均成為派生類的Protected
成員,並且
基本類的所有Protected
成員都將成為派生類的Protected
成員。
代碼示例:
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 ++是按類而不是按對象工作的。
一個很好的例子是,在復制構造函數或“復制分配”運算符函數中,可以訪問正在傳遞的對象的所有成員。
-派生類只能訪問其自己的基類的成員
考慮以下代碼示例 :
class Myclass
{
protected:
int x;
};
class derived : public Myclass
{
public:
void f( Myclass& obj )
{
obj.x = 5;
}
};
int main()
{
return 0;
}
它給出了一個編譯錯誤:
prog.cpp:4:錯誤:“ int Myclass :: x”受到保護
因為派生類只能訪問其自己的基類的成員。 請注意,此處傳遞的對象obj
與訪問它的derived
類函數沒有任何關系,它是一個完全不同的對象,因此derived
成員函數無法訪問其成員。
friend
? friend
如何影響訪問規范規則? 您可以將一個函數或類聲明為另一個類的friend
。 這樣做時,訪問規范規則不適用於friend
類/函數。 該類或函數可以訪問該特定類的所有成員。
那
friend
的包裝破裂了嗎?
不,他們沒有,相反,它們增強了封裝!
friend
飛船用於表示兩個實體之間的故意強耦合 。
如果兩個實體之間存在特殊關系,使得一個實體需要訪問其他private
或protected
成員,但是您不希望每個人都可以使用public
訪問說明符進行訪問,則應該使用friend
。
Scott Meyers在Effective C ++中的解釋可能有助於理解何時使用它們:
公共繼承應為“是一個關系”建模,而私有繼承應為“按條件實現”模型-因此,您不必遵循超類的接口,而只是在重用實施。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.