質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1392閲覧

constメンバーとそれに似たまぎわらしいメンバー

reotantan

総合スコア295

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2015/11/08 11:47

下の関数の使い分けを理解するために
int get() const {return x;} // const member function
const int& get() {return x;} // member function returning a const&
const int& get() const {return x;} // const member function returning a const&
コードを書いたのですが定義の時点でエラーがでています。
各コードは同じクラス内で共存できないような感じを受けたのですが、どのようにコードを編集したらいいか教えてください。よろしくお願いします

コード #include<iostream> using namespace std; class Myclass{ int x; public: Myclass(int val):x(val){} const int& get() const{return x;} int get() const {return x;} const int& get() {return x;} }; void print(const Myclass& arg){ cout<<arg.get()<<'\n'; } int main(){ Myclass foo(10); print(foo.get()); const Myclass fai(20); print(fai.get()); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

C++の仕様で、引数が同じで関数へのconst修飾の有無も同じで戻り値の型だけが違うメンバ関数は同居できません。

const int& get() const{return x;}

int get() const {return x;}

がそうなります。
たぶん、エラーメッセージにもそのようなことが書かれていると思うのですが。

同じ関数名でないと困るというのでなければ、関数名を変えるのが手っ取り早いと思います。

投稿2015/11/08 12:05

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2015/11/08 12:08

おお、const修飾が異なると別関数になるのですね。 C++は奥が深い。
catsforepaw

2015/11/08 12:14

特にアクセッサメソッドではそういうことをしますよね。同じ関数名だけど書き込み可能版と読み込み専用版を用意するようなところで。
reotantan

2015/11/08 12:35

なるほど、そういう事ですか。違う名前をつけるようにします。 ありがとうございました
Chironian

2015/11/08 13:27

> 特にアクセッサメソッドではそういうことをしますよね。 アクセサで使うのですか? set(xx) const;はあり得ないし、const修飾しないget();は不要な気もします。 ああ!! メンバー変数の非constなポインタや参照を返却したい場合に使うのですね。 メンバー変数の非constなポインタや参照を返却するってことは、そのメンバー変数をpublicに定義するのと大差なくなるのであまり頻繁には使わないかも?
catsforepaw

2015/11/08 13:35

よくお目にかかるのはSTLコンテナのbeginとかendとかfrontとか、constあり版となし版が用意されていますよね。 あ、もしかしてそういうのはアクセッサとは呼ばないのかな……? メンバ変数へのアクセスはとりあえずアクセッサと呼んじゃっていました……。
Chironian

2015/11/08 14:07

なるほど。 メンバー変数の参照やポインタを返却するものはアクセサっぽくないように感じます。 メンバー変数の実装を外部から隠蔽することがアクセサの主目的と理解していますので。 ところで、調べてみたところ、確かにconst有り無しによるオーバーロードはイテレータを返す時に良く使われるみたいですね。std::vector<>を内部に持つクラスが、find系の機能とinsert系の機能の両方を提供する時に必要になると理解しました。後、operator[]やat()でも使われているようです。 なるほど、コンテナ・クラスではマジ必要ですね。 catsforepaw さん、おかげて良い勉強になります。ありがとう。 reotantanさんも良い質問をしてくれてありがとうです。
guest

0

ベストアンサー

こんばんは。

get()関数をオーバーロードしようとしているのだと思います。
オーバーロード関数はパラメータにより区別されますが、パラメータが無いので全て同じ関数として識別されてしまいます。つまり「同じ」関数をいくつも定義していることになります。
全て異なる関数名にすると良いですよ。

投稿2015/11/08 11:56

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

reotantan

2015/11/08 12:00

なるほど、constだとかconstではないとかで区別はされないんですね。 解説ありがとうございます!
reotantan

2015/11/08 13:09

追記なのですが、const int&というのは変更できないint値を返すという事はわかるのですが、この書き方に毎回違和感を感じてしまいます。 chironian様はどのように捉えていますか?
Chironian

2015/11/08 16:09 編集

どこに違和感を感じるでしょうか? 組み込み型(classやstruct以外の型)を参照で返却する意味はあまりないので、わざわざ参照にしていることには私も違和感を感じます。普通は単にintで返却すると思います。 あと、本当はint const &と書いた方が意味を把握しやすいです。(私自身はconst int &の順序に慣れてしまっているので、この習慣を改めようと思っているところです。) ポインタの例になってしまいますが、  ①const int* p; constなint型へのポインタ  ②int const* p; int型←それはconst←そこへのポインタ  ③int* const p; int型←そこへのポインタ←それはconst ①と②はpの指す先のint型変数の値を変更できないですが、他のint型変数を指すようにpの値を変更できます。 ③はpの値を変更できないですが、pの指すint型変数を値は変更できます。 なので、③はconstな「int型へのポインタ」とも表現できますが、このように表現すると、①と非常に混同しやすいです。 その延長線で、参照の場合も、int const &と書いた方が誤解しにくいのです。
reotantan

2015/11/08 20:35

なるほど、const int&(参照) const int(変更できないint)と二つの書き方ができそうですね。丁寧な解説ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問