[英]Default inheritance access specifier
例如,如果我有兩個類A
和B
,則類B
繼承A
如下:
class B: public A
在這種情況下,我正在做public
繼承。
如果我把前面的代碼寫成如下:
class B: A
我將在這里進行什么類型的繼承(即公共)? 換句話說,默認訪問說明符是什么?
這里只是一個附帶問題。 我是否調用前一行代碼statements
? 特別是我記得我在C++ 無所畏懼:讓你感覺很聰明的初學者指南一書中讀到, statements
以;
結尾;
. 你怎么看?
謝謝。
只是對所有現有答案的一小部分補充:繼承的默認類型取決於繼承(派生)類型(示例中的B
),而不是被繼承的類型(基礎)(示例中的A
)。
例如:
class A {};
struct B: /* public */ A {};
struct A {};
class B: /* private */ A {};
它對於類是私有的,對於結構是公共的。
旁答:不,這些是根據標准對類的定義。 類定義以分號結尾。 另一方面,並非所有語句都以分號結尾(例如, if
語句不以分號結尾)。
當您從另一個類繼承一個類時,默認訪問說明符是私有的。
#include <stdio.h>
class Base {
public:
int x;
};
class Derived : Base { }; // is equilalent to class Derived : private Base {}
int main()
{
Derived d;
d.x = 20; // compiler error becuase inheritance is private
getchar();
return 0;
}
當您從另一個類繼承結構時,默認訪問說明符是 public。
#include < stdio.h >
class Base {
public:
int x;
};
struct Derived: Base {}; // is equilalent to struct Derived : public Base {}
int main() {
Derived d;
d.x = 20; // works fine becuase inheritance is public
getchar();
return 0;
}
如果您使用class
來定義您的類,則默認訪問說明符將為private
。 (我也認為這是錯誤的。)但是,如果您使用struct
,它將是public
。
我認為,類定義是聲明。 語句是轉化為實際代碼的內容(除非優化掉,無論如何)。
然而,C 和 C++ 的一個有點奇怪的特性是表達式是語句。 這就是為什么3+4;
是 C++ 中語法上合法的語句(盡管許多編譯器會警告它無效)。 雖然在這種情況下這顯然是無稽之談,但通常表達式會評估它們的副作用。 (一個明顯的例子是丟棄函數的返回值。調用函數不是為了獲得結果,而是為了它的副作用。)
繼承的“類型”取決於類的定義方式。 有應用於繼承的默認訪問說明符。 從 C++ 標准:
在沒有訪問說明符為基類的,當派生的類與類密鑰定義假定公共
struct
,並且當類與類密鑰定義的私人假設class
。 [ 示例:class B { /* ... */ }; class D1 : private B { /* ... */ }; class D2 : public B { /* ... */ }; class D3 : B { /* ... */ }; // B private by default struct D4 : public B { /* ... */ }; struct D5 : private B { /* ... */ }; struct D6 : B { /* ... */ }; // B public by default class D7 : protected B { /* ... */ }; struct D8 : protected B { /* ... */ };
這里B是D2、D4和D6的公共基地,D1、D3和D5的私人基地,以及D7和D8的保護基地。 — 結束示例 ]
繼承的默認類型在 C++ 中是私有的。
class B:A
{};
相當於
class B: private A
{};
如果不選擇繼承,C++ 默認為private
繼承,就像類成員默認為類的private
訪問一樣。
作為您遇到的其他鑄造問題
class A { virtual void test() = 0; };
class B : virtual public A { virtual void testb() {} };
class C : virtual public A { virtual void testc() {} };
class D : public B, public C {
virtual void test() override {}
}
void main() {
D d;
void* v = &d;
A* a = &d;
((D*)A)->test(); //OK
((D*)v)->test(); //undefined behavior (that call testb() in vtable logic at 1st inheritance position)
dynamic_cast<D*>(v)->test(); //compile error cast from void* not permitted
//resolution
void* x = a;
((D*)x)->test(); //OK but as you can see, you must to store a* in x*
}
默認訪問說明符是類和結構之間的重要區別。 默認情況下,它對於結構是公共的,對於類默認是私有的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.