

c++ で例えば、
class A
{
public:
virtual ~A() {}
};
class B
{
public:
virtual ~B() {}
virtual B& hoge() = 0;
};
class D:
public A,
public B
{
public:
virtual D& hoge() // この戻り値でエラー
{
...;
return *this;
}
};
のようにコードを書いたとします。
そして、これを gcc 3.3 でコンパイルしたところ「ゴメン。共変はサポートしてないんだ」って感じでエラーとなってしまいました(gcc 3.2 では問題を孕んでたくせに、何も言わずにコンパイル通ってました)。
この共変の意味や、その実際の挙動、問題点等は判ったのですが、では一体、この様な場合にどのようにコードを修正するのが正しいのか思い至りません。
どなたか、私ならって言うお考えがあればご教示願えないでしょうか?
ちなみに、コンパイラーを変えるってのは無しです^^)
## gcc 4.0 ならいけるのかな??
No.4ベストアンサー
- 回答日時:
どうしてもコンパイラを変えたくないなら、他の回答にあるように、返却値を B& にするしかないと思います。
若干補足すると、フリー関数として、inline B& hoge(B& b)
{
return b.hoge();
}
inline D& hoge(D& d)
{
return static_cast<D&>(d.hoge());
}
を作っておけば、多くの問題は解決するかと思います。
ちなみに、gcc-3.4.4ではこの不具合は解決していました。というわけで、gcc-4.0.0でも問題ないと思います。
ご回答ありがとうございます。
No.3 さんのお礼にも記述させてもらいましたが、今回の件は私の単なる勘違いでした。よって、実体化できない クラス B の リファレンスが派生クラスで戻せるなら、とりあえず問題は解決です。
ご提示頂いたアイデアは良いですね。C++ では、ついつい何でも method にしがちですが、クラスに属さない関数を利用したテクニックには私も最近気付き、色々と応用を考え始めたところでした。このアイデアも頂かせてもらいます ^^)
No.3
- 回答日時:
> 「ゴメン。
共変はサポートしてないんだ」> よって、その参照もエラーとなってしまいました。
エラーについてはエラーメッセージを正確に書いて下さい。
そうしないと、誤解が生じて質問者も回答者も損をします。
> 今回の件では class B は抽象クラスのため、実体化できません。
どこで実体化したのですか?
今まで提示されたコードはどこにもBを実体化するようなコードはありません。
> そうですね。でも、面倒というより、無ければ実際に困ってしまいます^^)
covariantが使えないとプログラムが作れないというわけではないと思います。
コンパイラが変えられない以上、簡潔さを多少妥協することをお勧めします。
> エラーについてはエラーメッセージを正確に書いて下さい。
> そうしないと、誤解が生じて質問者も回答者も損をします。
すいません。手元にはそのコンパイラが無かったのと、今回の件はそのエラー自体を主題と思っていなかったため、適当に覚えていた内容を記述してしまいました。
> どこで実体化したのですか?
> 今まで提示されたコードはどこにもBを実体化するようなコードはありません。
あれ!! 当方の勘違いだったようです。
ちょっと間抜けな事に別の部分で実体化できないと出ていたエラーを、この hoge() の部分と思い込んで、実体化できないクラスはその参照も返せないんだと勝手に思っていました。
実体化できないクラスでもその参照は返せるのですね。
と言う事はとりあえず問題解決です。
> covariantが使えないとプログラムが作れないというわけではないと思います。
> コンパイラが変えられない以上、簡潔さを多少妥協することをお勧めします。
確かに仰せのとおりですね。最悪は妥協も考えていましたが、これらのクラスを Template 等で meta programing 的に利用しようとすると、syntax は非常に重要となってしまいます。それで可能な限り突き詰めようと模索していました ^^)
No.2
- 回答日時:
class Dの関数hogeを
virtual B& hoge()
{
return *this;
}
と派生元と合わせ、hogeを呼び出しているほうでキャストしましょう。
D d;
D& hoge = static_cast<D&>(d.hoge());
面倒ですね。
面倒だからこんなキャストをしなくて良いように、covariant(共変?)という機能が追加されたのでしょう。
ご回答ありがとうございます。
そうですね。でも、面倒というより、無ければ実際に困ってしまいます^^)
あまり、困っている人は居ないのかな??
No.1
- 回答日時:
ところで共変って何ですか?
今回の場合は、パラメータが一緒で戻り値の型のみが異なるhogeがオーバーロードされたことが原因のはずですが。
クラスBのhogeが純粋仮想関数になっているので、対応方法は
クラスDのメソッドも
B& hoge()
にするのが正しいと思います。
で、使う側がdynamic_castでキャストをする感じかと。
ご回答ありがとうございます。
確かに dynamic_cast を利用するもの一つの方法かと思うのですが、今回の件では class B は抽象クラスのため、実体化できません。よって、その参照もエラーとなってしまいました。
じゃあ hoge() の戻り値を B のポインターにすればよさそうなものですが、そうすると下記の記述ができません。
## 例えば、B に hoge() 以外に B& move(...), B& scaled(...),
## B& rotate(...) 等があったとき、
##
## D d;
## d.move().scaled().rotate();
### ポインターにすると、
### d.move()->scaled()->rotate();
### になりますが、ちょっと美しくありません。
で、共変の許されていない環境では、みなさん一般的にどうされているのかな? と思った次第です。
==
ちなみに共変ですが、英語では covariant と表記されていました。
「C++ 共変」で ググッてみたところ、
http://www2s.biglobe.ne.jp/~ragnarok/program/cpp …
のようなページが見付かりました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java 直し方について教えて頂きたいです。 4 2022/08/13 02:11
- Java java final 1 2022/06/10 22:49
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- その他(開発・運用・管理) WindowsからSSHでサーバーにあるファイルをダウンロードできない…。 3 2022/04/24 11:08
- C言語・C++・C# PC画面を録画するプログラムでdllの読み込みエラー 1 2023/04/22 08:31
- Java javaのクラスの分け方について質問です。 APIの内部用と外部用でクラスを分けたいのですがインター 2 2022/04/26 16:06
- Java eclipse実行ができない 2 2022/07/27 04:47
- Visual Basic(VBA) VBA リボンののリカバリーでオーバーフローエラーになります 2 2023/07/04 19:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数の入れ子ができない。
-
正規表現に関する質問です。HTM...
-
number_formatが勝手に四捨五入
-
正規表現 ファイル名の取得
-
PHPでXMLの置換 replaceData
-
こういう事できますか?
-
VCでJetによるCSVファイルの読...
-
クラス内で上位クラス内メンバ...
-
外部ファイル(テキスト)を取...
-
String変数の文字列の検索方法
-
Fatal error: Cannot use []
-
ユーザー関数の外の変数は呼べ...
-
現在PHPとsmartyを勉強している...
-
静的多態性と動的多態性の共存...
-
PHP の system コマンド
-
VBA コレクションに2次元配列...
-
phpでmysqldump作成
-
.htaccessについて
-
C++ 共変 戻り値について
-
PHP3からPHP5にVerUpすると動作...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA コレクションに2次元配列...
-
VB.NETからVBAマクロ(引数)を呼...
-
PHP、ヒアドキュメント内でのIF...
-
エラーの理由が分りません。Pri...
-
どういうプログラムを関数化を...
-
可変変数にアロー演算子を使いたい
-
protectedなのにアクセスできな...
-
PHPの名前空間インポートについて
-
ASPのResponse.WriteをPHPでは...
-
[C++]std:mapの扱いを教えて頂...
-
vb作成したらでbeep音が鳴りま...
-
PHPの変数値をリンクさせたい
-
次のhtml・cssでspan内の文字を...
-
既存関数の上書き
-
classの再定義エラーについて
-
[C#]Arraylistに追加した構造体...
-
.htaccessについて
-
共用体のサイズをsizeofで
-
PHPで呼び出し元の関数名の取得...
-
PHPでの画像の形式の変換
おすすめ情報