私はそれが派生オブジェクトに対して呼び出されたとき、それはDescendant.Iを返すことのようにDeriveds fooのを書きたいが、これは共変戻り値の型の使用を簡単に行うことができることを知っています。しかし、もし私がこの機能を使うことができなかったらどうしますか?どのように私は上記のコードでこの機能をシミュレートできますか?シミュレート共変戻り値の型の挙動
答えて
Ancestor * Derived::foo
{
// Do whatever
return new Descendant ();
}
ポインタを使用できる場合は、アップキャストされたDecendポインタを返します。返されたポインタはDescendantを指し、メソッドが仮想であると仮定すると、同様にDescendentのように動作します。
はい - ここでの重要な点は、この単純な文書の明示的な文書として共変の戻り値型が追加されたことです(より多くのコンパイラチェック、APIのより有益な戻り型、可能性のある追加の最適化を可能にする) - 多型は、共変リターン型が導入される前にうまく動作し、下位互換性を保持します。 –
派生オブジェクトのために呼び出されたときにDescendantを返すように、派生クラスfooを記述します。
foo
ので
// Do not redefine foo as : Descendant foo(void);
値によってAncestor
を返して、達成する唯一の方法(の限られた種類の)共分散foo
を再定義することです。したがって、の要件は矛盾しているです。
C++は、共変量生ポインタと生の参照結果をサポートします。 boost::shared_ptr
やstd::auto_ptr
などのスマートポインタの結果型では、派生クラスでpublic関数を再定義することによって共分散を実装する必要があります。これはあなたの問題に似ています。なぜなら、共分散関数は生ポインタまたは生の参照ではなく–の値を返すからです。–しかし、’もあなたの問題と異なります。スマートポインタのタイプ間に継承関係はありません。 。ここ
は例です:二つの第一foo
で
#include <memory>
#include <typeinfo>
using namespace std;
struct Ancestor{ virtual ~Ancestor(){} };
struct Descendant : Ancestor {};
class Base
{
protected:
virtual Ancestor* virtualFoo() const
{
return new Ancestor();
}
public:
auto_ptr<Ancestor> foo() const
{
return auto_ptr<Ancestor>(virtualFoo());
}
};
class Derived : public Base
{
protected:
virtual Descendant* virtualFoo() const
{
return new Descendant();
}
public:
auto_ptr<Descendant> foo() const
{
return auto_ptr<Descendant>(virtualFoo());
}
};
#include <iostream>
int main()
{
Base baseObject;
Derived derivedObject;
Base& baseRef = derivedObject;
cout << typeid(*baseObject.foo()).name() << endl;
cout << typeid(*derivedObject.foo()).name() << endl;
cout << typeid(*baseRef.foo()).name() << endl;
}
は、静的結果タイプは、共分散は、すべて使用してコード’の視点から約あるものであるダイナミック型、に対応する呼び出し。
指示先オブジェクトタイプであるが、最後のfoo
呼び出しでfoo
結果の静的タイプは、std::auto_ptr<Ancestor>
あります。
仮想関数のオーバーライドは、C++ ’のrawポインタ型の共変結果の組み込みサポートに依存します。
乾杯& HTH。、 `基本::値で` Ancestor`を返しfoo`として
- 1. Javaの共変量戻り型
- 2. 異なる戻り値の型を持つ列挙型Func
- 3. 共変戻り値の型があるJavac
- 4. soapcpp2の戻り値としての列挙型
- 5. 戻り値の型
- 6. 戻り値の型
- 7. Scalaの戻り値の型
- 8. 関数の戻り値の型で存在量の数量をシミュレートする
- 9. 戻り値型インターフェイス
- 10. 静的戻り値の型
- 11. Linqと戻り値の型
- 12. ジェネリック戻り値の型
- 13. は、戻り値の型
- 14. Haskellの戻り値の型多型
- 15. パラメータの型 - >戻り値の型
- 16. 動的型の戻り値型を決定する
- 17. Javaの戻り値の型enum値
- 18. 列挙型の間の共有メソッド
- 19. デフォルトのCのboolean型の戻り関数の戻り値++
- 20. スレッドオブジェクトのgetId()の戻り値の型
- 21. jQuery attr戻り値の型の最近の変更?
- 22. 戻り値の型としての動的
- 23. クロージャの戻り値の型構文
- 24. jQueryデータ型の戻り値のグループ化
- 25. 空の戻り値の型C++
- 26. グラフAPIの戻り値の型はANDROID
- 27. java generics - メソッドの戻り値の型
- 28. 機能戻り値の型の問題
- 29. 戻り値の型/メソッドの代替?
- 30. API配列の戻り値の型
...とにかく '派生:: foo'のための共変戻り値を持つことができませんでした。実行時の多態性は、ポインタまたは参照と仮想ディスパッチを介して機能します。あなたの本当の問題を知らずに、あなたに何が役に立つかを知るのは難しいです。例えば、祖先への参照やポインタを返すことができますか? –
はいできます。私の質問は、 "共変な戻り値の型をサポートしていないコンパイラ(古いもののような)でこの問題を解決するにはどうすればいいですか" – thikonom