4

C ++でプライベート基本クラスへのキャストを実装するにはどうすればよいですか?友達を追加するなどのハックは使いたくない。パブリックキャスティング演算子の定義は機能しない。

編集 :

たとえば、私は持っています:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

EDIT2

なぜ私はこれをするのですか?

非常に重量があり、いくつかの同様のタイプ(VelocityX VelocityYなど)のプロパティを定義する必要があるとします。次に、これらのプロパティの任意のセットを持つことができるクラスを持つことができるようにしたいと思います。これらのプロパティを処理したい場合は、バリエーションごとに実装を追加するのではなく、基本タイプにキャストしたいのは明らかです。プライベートインターフェイスを暗黙的に表示するよりも、必要な場所に明示的にキャストする方がよいため、パブリック継承は使用しません。本当の問題ではありませんが、解決策が欲しいです:)

4

3 に答える 3

6

パブリックキャスティング演算子の定義が機能しない場合は、通常の関数を試してみてください。

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

とにかく、ポイントは何ですか?Dから個人的に派生する場合は、外部からをとしてB使用することは想定されていません。DB

于 2010-09-17T20:06:42.873 に答える
3

Cスタイルのキャストを使用できます。「ハック」や「実装」は必要ありません。それを明示的な関数にラップすると、「Cスタイルのキャストは悪い」人々に役立ちます

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

Targキャストを安全にするには、それが実際にプライベートまたはパブリックベースであることを確認する必要があります。これはによって行われboost::is_base_ofます。


もちろん、そのようなキャストを行うのではなく、ベースポインタを返すそれぞれの派生クラスのメンバー関数を優先する必要があります。


パブリックキャスティング演算子の定義は機能しません。

それは私には意味がありません...なぜ基本クラスをプライベートにするのですか?公開するだけです。変換関数が機能しない理由は、標準では、暗黙の変換で基本クラス、クラス自体、または。への変換関数が考慮されないことが要求されているためvoidです。

于 2010-09-17T20:06:37.253 に答える
0

これにはユースケースがあります。私は常に関数を追加している大きくて揮発性の基本クラスから継承していますが、基本クラスの関数がサブクラスで正しく機能することはほとんどないため、プライベートに継承します。

基本クラスを返す関数を作るのが一番簡単だと思います。以下に、完全に修正されたプログラムを示します。関数名として「do」などの識別子を使用すると、すべてのコンパイラが不幸になる可能性があるため、質問を送信する前にコードをコンパイルしてみてください。..:-(:-(

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

于 2015-04-22T21:12:59.560 に答える