![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_13.png?5a7ff87)
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ランキング
-
VBA コレクションに2次元配列...
-
classの再定義エラーについて
-
可変変数にアロー演算子を使いたい
-
PHPの変数値をリンクさせたい
-
関数の動きと記述方法の意味を...
-
PHPで、相対的な変数名の場合の...
-
サブネットマスクを用いたIP制...
-
Fatal error: Cannot use []
-
VB.NETからVBAマクロ(引数)を呼...
-
デフォルトの定義済みクラスに...
-
共用体のサイズをsizeofで
-
【Objective-c】rubyの__send__...
-
既存関数の上書き
-
VB6のコンボボックスのテキスト...
-
PHPプログラム上で「URLを直接...
-
PHP Catchable fatal error の...
-
PHP、ヒアドキュメント内でのIF...
-
メール本文の構成 行頭空白
-
Dosブロンプトでtabを出力したい
-
wordの差し込み印刷で文字...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA コレクションに2次元配列...
-
エラーの理由が分りません。Pri...
-
可変変数にアロー演算子を使いたい
-
VB.NETからVBAマクロ(引数)を呼...
-
PHP、ヒアドキュメント内でのIF...
-
VB.NETSystem.Xml 要素数を得る...
-
どういうプログラムを関数化を...
-
vb作成したらでbeep音が鳴りま...
-
次のhtml・cssでspan内の文字を...
-
classの再定義エラーについて
-
既存関数の上書き
-
protectedなのにアクセスできな...
-
配列の操作時にLNK2001外部シン...
-
UNIX CP "で上書きしません"
-
PHPでの画像の形式の変換
-
PHPプログラム上で「URLを直接...
-
Let's Encryptで自動更新がされ...
-
ExcelVBAで部分一致(*)をしたい
-
VB6のコンボボックスのテキスト...
-
ASPのResponse.WriteをPHPでは...
おすすめ情報