- ベストアンサー
const参照をポインタ引数として渡すには?
Aというクラスがあって、BはAを継承しているとします。 そこで、Bのconst参照を返却する以下の関数定義があったとします。 const B& getB() { return b; //bはB型 } さらに次の関数があります。 void C(A* a) { //適当な処理 } ここでCを以下のように呼ぼうとするとコンパイルエラーになります。 C(getB()); Cは引数として型Aを求めていますが、BはAを継承しているので、 そのまま渡しても問題ないと思います。 次に、Cは引数としてポインタを求めているのにgetBの戻り値の参照をそのまま 渡しているからまずいのだと思い、以下のようにしました。 const B& hoge = getB(); C(*hoge); //参照をポインタに変換 しかし、さらに型が違うとエラーになります。 どこがまずいのでしょうか? それと、上では参照をポインタに変換するために変数hogeを宣言していますが、 それを省略して一気にやる方法はないでしょうか? C(*getB()); のようなやり方がしたいのですが。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>C(*hoge); //参照をポインタに変換 これはちがいますよ~ やるなら C(&hoge); ですね。 さらに C(A* a) では、const でないポインタを受け付けているので C((A *)&hoge); みたいにキャストしないとダメですね。 キャストについては const_cast とか調べてくださいね。
その他の回答 (3)
- 1839cc
- ベストアンサー率54% (12/22)
> 関数Cが、ライブラリなどに含まれるような自分で修正できない関数の場合、実引数を変更することがないことを確認してください。 > 実引数を変更することが絶対にないのであれば、tochanxさんの方法が正しいです。 すみません、「clsdi99さんの方法」の間違いです。
- 1839cc
- ベストアンサー率54% (12/22)
ちょっとまって!!!!! clsdi99さんのやり方でコンパイルは通るようになりますが、 その処理(tochanxさんがやりたい事)は、そもそも正当な処理ですか?! 関数Cは誰が作った関数で、何をする関数なの?! というのも、関数getBが返す参照にはconstがついています。 これは、「元データは絶対に変更されたくない」ということの意思表示です。 しかし、関数Cが受け取るのはconstのないポインタ。 つまり、「実引数を変更しますよ」という意思表示がされている可能性があるのです。 さらに、参照ではなくポインタを使うことで、その意思表示をより直感的にしている可能性もあります。 このような場合、getBの戻り値を渡すこと自体が間違いです。 もし、関数Cが自作関数で、実引数を変更することがないのであればkoedameさんの回答が正しいです。 関数Cを修正してください。 関数Cが、ライブラリなどに含まれるような自分で修正できない関数の場合、実引数を変更することがないことを確認してください。 実引数を変更することが絶対にないのであれば、tochanxさんの方法が正しいです。 しかし、Bのサイズがよほど大きくない限り、「関数Cが実引数を変更する場合」の方法を用いてください。 関数Cが実引数を変更する場合、以下のようにgetBの戻値を一時変数に複製するなどの対処法が正しいかと思います。 B hoge = getB(); // 注:一時変数は参照型ではない。 C(&hoge); // 元データは変更されない。 getBの元データを本当に変えたいのだとすれば、それは設計ミスを疑ってください。 よっぽどパフォーマンスに問題がない限り、そんなコードを書くべきではありません。
お礼
まさしくライブラリの関数なのですが、 実引数を変更することが絶対ないとは言い切れないですし、 おっしゃるとおり変更される可能性が高そうです。 一時変数に複製する方法でやりたいと思います。 ありがとうございました。
- koedame
- ベストアンサー率33% (10/30)
引数事態がポインターなので値が変更できてしまうし、 参照とポインターは”別”と判断されているので ここは、関数C()の定義を C(const A &a ) { //処理 } にしてみてください。
お礼
すみません。関数Cはこちらからはいじれない状況なのです。 記述不足でした。ありがとうございました。
お礼
了解です。const_castで調べてみます。 ありがとうございました。