簡體   English   中英

默認繼承訪問說明符

[英]Default inheritance access specifier

例如,如果我有兩個類AB ,則類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++ 標准:

[class.access.base]/2

在沒有訪問說明符為基類的,當派生的類與類密鑰定義假定公共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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM