2013-07-29 3 views
15

これを行うことはできますか?Cスタイルのキャストを使用して、派生クラスをプライベートベースクラスにキャストできますか?

class A { ... }; 

class B : private A 
{ 
    const A &foo() const 
    { 
     return *((const A *)this); 
    } 
}; 

私は、基本クラスから継承する個人サブクラスを取り、その基底クラスの公開バージョンにキャストすることはできますか?私はそれが仮想メソッドを持っていなくてもこれを行うことができますか?

私の推測ははいですが、安全で可搬性があることを確認したかったのです。

+0

私はそれが可能だと思いますが、それは私的継承の目的をちょっと打ち負かしてしまうかもしれませんが... – Nbr44

+0

"私的な"継承の意味に従うのは良いことではないでしょう。この種の継承は、「実装されている」という意味であり、公開継承は「is-a」関係です。 – JBL

+0

なぜこの恐ろしいハックが最初に必要なのですか? –

答えて

14

はいすることができます:標準の§5.4/ 7:

...以下はstatic_castとreinterpret_castは操作 は、(必要に応じてconst_castを操作続いて)明示の キャスト表記を使用して行うことができます基本クラス タイプにアクセスできない場合でも、変換を入力:

ポインタを派生クラスタイプのオブジェクトまたは派生 クラス型の左辺値には明示的 明白へのポインタまたは参照に変換することができますそれぞれ基本クラス型。

には私的継承の目的を破ってはいけません。

+0

C++はほぼ10年間続いていますが、私はまだこの言語のコーナーを発見しています。それが言語や悪い点についての良いコメントであるかどうかは不明です。おそらく悪い。しかし、ねえ、なぜ今停止しますか? :) – AdamIerymenko

+1

本当にそれは多くのトリッキーなコーナーがあります。裸のポインタ、新しい[]、ダングリング参照、非仮想的なデストラクタ、std :: auto_ptr(ありがたいことに非難されています)私はリストにテンプレートを追加するように誘惑さえするだろうが、それはdownvotes /一般的な嘲笑を危険にさらすだろう! – Bathsheba

+0

しかし、テンプレートは楽しいです!実際には、彼らは間違いなくスイス軍バズーカのカテゴリで*過度に使用されない*しかし、言語の私のお気に入りの部分です。 – AdamIerymenko

-5

あなたの質問に基づいて、答えは異なります。しかし、あなたのソースコードでは、答えはyesです。

answereに影響を与える2つの要因があります:変換なしフィットネスエクササイズ場合はキャストが再interpertキャストを呼び出すため

  1. は、あなたがCスタイルのキャストを使用している場合、それはそうでしょう。ターゲットタイプのポインターに任意のタイプのポインターをキャストできます。しかし、MIがある場合、結果はほとんどのC++言語の実装では正しくない可能性があります。

  2. メンバ関数内でキャスト(Cスタイルキャストなし)を行うと、メンバークラス内で基本クラスにアクセスできるため、answereはyesになります。式が基本クラスにアクセスできない場所にある場合、コンパイルエラーが発生します。

標準converstionについての詳細は、Cであり、++標準

A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D. 
If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. 
The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type. 

編集2:answere詳細を確認します。

+2

これは正しくありません。他の答えをお読みください。 – Bathsheba

+4

あなたが引用した段落は暗黙の*型変換についてです。基本クラスにアクセスできない場合は、派生クラスポインタをそのクラスに変換できないことがあります。派生クラスの内部では、基本クラスにアクセスできるので、これは適用されません。さらに、Cスタイルのキャストの特別なルールがあります。[Bathsheba](http://stackoverflow.com/users/2380830/bathsheba)の[answer](http://stackoverflow.com/a/17925216/) 420683)。 – dyp

+0

"Cスタイルのキャストを使用している場合は、キャストは変換が利用できない場合は再中間キャストを呼び出すため、はいとなります。いいえ、このケースでは、Cスタイルのキャストは引用されたBathshebaという特別なルール(つまり、基底クラスにアクセスできないということを無視する)によって 'static_cast'と同様に動作します。引用符を挿入するには、 '>'または引用ボタンを使用してください.4つのスペースやコードボタンは挿入しないでください。 – dyp

8

はい、明示的に許可されています。ユースケースは限られたかもしれないがだから、いくつかは、そこにある

template <typename Policy> 
class foo : Policy 
{ 
    public: 
     void do_something() 
     { 
      Policy & p = *this; 
      p.do_something(); 
     } 
}; 

:アレキは彼の政策のアプローチに基づいた設計のためModern C++ Designで広くこれを使用しています。

+4

これはCスタイルのキャストじゃない?それはクラスの中から私的ベースへの暗黙のキャストです。何か不足していますか? – unkulunkulu

+0

暗黙のキャストは、Cスタイルのキャストよりも制限されています。 – nijansen

+0

答えのコードサンプルにはCスタイルのキャストは含まれておらず、ベースクラスの 'Policy'にアクセスできないコードもありません。したがって、OPが求めていたことには関係していないようです。 – Quuxplusone