C ++は(仮想)プライベート基本クラスをコンパイラーで削除できますか?

ジャック・サバス

次の例を考えます。

class A
{
    protected:
        static void useful_function_without_side_effects() {...}
}

class B : private A
{
    // B has no friends :(

    public:
        void travel_back_in_time() { super_useful_function(); }
}

質問1:コンパイラが基本クラスAを最適化することは許可されますか?この基本クラスは実際にはBに影響を与えないため、または実行時の動作にはまったく影響しませんか?

質問2:継承がこのようにプライベート仮想として宣言された場合、これは変更されますか?

class B : private virtual A
エソリス

回答1:

非多態性クラスには、実行時に完全に代表がありません。存在する可能性があるのは、関数と見なされるオブジェクトとメソッドだけです。このクラスは、オブジェクトの一部にアクセスし、メソッド呼び出しを定義どおりに解決するようにコンパイラーに指示するだけです。直接解決されると、すべてがランタイムコードにハードコードされます。private修飾子は、ここには何も変わりません。

Bによって派生したAクラス(フィールドを持たない)は、クラスBのオブジェクトに「サイズを追加」しません。これは、Aクラスにフィールドがない場合は常に当てはまりますが、sizeof(A)は少なくとも常に1になります。Bのサイズがすべてのフィールドと基本クラスのサイズの合計でなければならないという規則もありませんが。

回答2

これにより、Bクラスにサイズが追加されます。規格はどのように正確ではありません。通常の実装では、常にBクラスのサイズを1ポインターのサイズに加えて、クラスAの可能なサイズだけ拡張します。

通常、仮想継承は「それ自体へのポインタ」を使用して実装されます。つまり、派生クラス(A)のサブオブジェクトは、物理的にオブジェクト全体の一部ですが、直接アクセスされることはなく、オブジェクト全体のポインターを介してアクセスされます。

これは、合計サイズが4のフィールドを持つフィールドレスAおよびBがある場合はさらに少なくなります。

物理的な継承:

B: [A: 0] [B extension: 4]

仮想継承:

B: [A virtual: <pointer size>] [B extension: 4] [A shared subobject: 1]

これらの順序は実装間で異なる場合がありますが、これはABI定義の一部であり、コンパイラのプライベートルールではありません(つまり、1つのプラットフォーム上のすべてのコンパイラが同じルールを使用する必要があります)。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

抽象クラスはC ++ 11でコンストラクターとプライベートメンバーを持つことができますか

分類Dev

C ++の基本クラスと派生クラスの「仮想」コンストラクターを宣言しますか?

分類Dev

c ++仮想ベースとして使用されるクラスは、パラメーターを持つコンストラクターを持つことができますか?

分類Dev

基本クラスのフレンド関数が、プライベートであるにもかかわらず、派生クラスのオーバーライドされた仮想関数をどのように呼び出しているか?(C ++)

分類Dev

C ++パブリックヘリテージベースクラスでは、派生クラスのプライベート仮想関数を呼び出します

分類Dev

C ++では、インスタンスをインスタンス化せずに、クラスのテンプレートに仮想デストラクタがあるかどうかをテストする(新しい)方法はありますか?

分類Dev

キャストなしでC#で「仮想コンストラクター」パターンを実装することは可能ですか?

分類Dev

C ++でプライベートコピーコンストラクターと削除済みコピーコンストラクターを使用する理由

分類Dev

テンプレートベースのC ++コードをコンパイルできません:クラスの前にtypenameが必要です

分類Dev

C ++:基本テンプレートクラス内で派生した特殊な仮想関数を呼び出す

分類Dev

C ++はプライベート純粋仮想メソッドをパブリックとしてオーバーライドします

分類Dev

クラスメンバー変数をC ++テンプレートでコンパイルしますか?

分類Dev

C ++では、仮想基本クラスとは何ですか?

分類Dev

コンパイル時にクラスにC ++ 17の仮想ベースがないかどうかを検出するにはどうすればよいですか?

分類Dev

仮想関数または非仮想関数がC ++の基本クラスに追加された場合、クラス階層全体を再コンパイルする必要がありますか?

分類Dev

C ++コンパイラはコンストラクト+ moveconstructをコンストラクトだけに置き換えることができますか?

分類Dev

C#でF#のコンストラクターパラメーターは自動的に不変のプライベートメンバー機能を取得する方法はありますか?

分類Dev

仮想関数を持つC ++クラスに重要なコピーコンストラクターが必要なのはなぜですか?

分類Dev

godbolt(コンパイラエクスプローラ)でC ++モジュールをテストする方法は?

分類Dev

C#で基本クラスのプライベートメソッドを非表示にする方法は?

分類Dev

C ++ 11コンパイラはアトミック変数の追加ロードを導入できますか?

分類Dev

派生クラスに、C ++の基本クラスにないコンストラクターを含めることはできますか?

分類Dev

C ++でプライベートテンプレートクラスからコンストラクターを継承する

分類Dev

C ++でプライベートテンプレートクラスからコンストラクターを継承する

分類Dev

C / C ++でunix / linuxコマンドラインツールを作成するためのベストプラクティスは何ですか?

分類Dev

C ++コンパイラの最適化は、スコープが終了する前に未使用のデータ構造をクリアできますか?

分類Dev

C ++ | 派生クラスは、それ自体のプライベートメンバーではなく、基本クラスのプライベートメンバーにアクセスしています

分類Dev

C ++:テンプレートクラスの仮想関数を正しくオーバーライドする

分類Dev

C ++で明示的にインスタンス化されたテンプレートメソッドが仮想メソッドをオーバーライドできないのはなぜですか?

Related 関連記事

  1. 1

    抽象クラスはC ++ 11でコンストラクターとプライベートメンバーを持つことができますか

  2. 2

    C ++の基本クラスと派生クラスの「仮想」コンストラクターを宣言しますか?

  3. 3

    c ++仮想ベースとして使用されるクラスは、パラメーターを持つコンストラクターを持つことができますか?

  4. 4

    基本クラスのフレンド関数が、プライベートであるにもかかわらず、派生クラスのオーバーライドされた仮想関数をどのように呼び出しているか?(C ++)

  5. 5

    C ++パブリックヘリテージベースクラスでは、派生クラスのプライベート仮想関数を呼び出します

  6. 6

    C ++では、インスタンスをインスタンス化せずに、クラスのテンプレートに仮想デストラクタがあるかどうかをテストする(新しい)方法はありますか?

  7. 7

    キャストなしでC#で「仮想コンストラクター」パターンを実装することは可能ですか?

  8. 8

    C ++でプライベートコピーコンストラクターと削除済みコピーコンストラクターを使用する理由

  9. 9

    テンプレートベースのC ++コードをコンパイルできません:クラスの前にtypenameが必要です

  10. 10

    C ++:基本テンプレートクラス内で派生した特殊な仮想関数を呼び出す

  11. 11

    C ++はプライベート純粋仮想メソッドをパブリックとしてオーバーライドします

  12. 12

    クラスメンバー変数をC ++テンプレートでコンパイルしますか?

  13. 13

    C ++では、仮想基本クラスとは何ですか?

  14. 14

    コンパイル時にクラスにC ++ 17の仮想ベースがないかどうかを検出するにはどうすればよいですか?

  15. 15

    仮想関数または非仮想関数がC ++の基本クラスに追加された場合、クラス階層全体を再コンパイルする必要がありますか?

  16. 16

    C ++コンパイラはコンストラクト+ moveconstructをコンストラクトだけに置き換えることができますか?

  17. 17

    C#でF#のコンストラクターパラメーターは自動的に不変のプライベートメンバー機能を取得する方法はありますか?

  18. 18

    仮想関数を持つC ++クラスに重要なコピーコンストラクターが必要なのはなぜですか?

  19. 19

    godbolt(コンパイラエクスプローラ)でC ++モジュールをテストする方法は?

  20. 20

    C#で基本クラスのプライベートメソッドを非表示にする方法は?

  21. 21

    C ++ 11コンパイラはアトミック変数の追加ロードを導入できますか?

  22. 22

    派生クラスに、C ++の基本クラスにないコンストラクターを含めることはできますか?

  23. 23

    C ++でプライベートテンプレートクラスからコンストラクターを継承する

  24. 24

    C ++でプライベートテンプレートクラスからコンストラクターを継承する

  25. 25

    C / C ++でunix / linuxコマンドラインツールを作成するためのベストプラクティスは何ですか?

  26. 26

    C ++コンパイラの最適化は、スコープが終了する前に未使用のデータ構造をクリアできますか?

  27. 27

    C ++ | 派生クラスは、それ自体のプライベートメンバーではなく、基本クラスのプライベートメンバーにアクセスしています

  28. 28

    C ++:テンプレートクラスの仮想関数を正しくオーバーライドする

  29. 29

    C ++で明示的にインスタンス化されたテンプレートメソッドが仮想メソッドをオーバーライドできないのはなぜですか?

ホットタグ

アーカイブ