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

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

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

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

Q&A

解決済

3回答

4352閲覧

c++: コンストラクタの仮引数の名前の付け方は?

Tteratail

総合スコア36

C++

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

0グッド

2クリップ

投稿2020/09/29 15:29

C++のコンストラクタに渡す仮引数の命名について教えてください。またがガイドラインがあれば教えて頂きたいです。
教えて頂きたいこと:

  1. メンバイニシャライザ(初期化子リスト)だと、コンストラクタの仮引数名がメンバ変数と同一でも問題なく初期化できいる?

  2. メンバイニシャライザを使わないと、コンストラクタの仮引数名がメンバ変数と同一だと正常に初期化できない?

  3. コンストラクタの仮引数の命名方法について常識やガイドラインはあるでしょうか?

 多くのサイトは同名でなく、プレフィックスやサフィックスとしてアンダーバーを付けたり、文字を短縮したりとしていました。一方で、同名で行けるんだから手間を省くために同名が効率的という意見もありました。

ご教授お願いします。

class Test { int a; int b; public: /* イニシャライザ不使用 */ //--- Constractor type1--- 初期化問題なし Test(int _a, int _b) { a = _a; b = _b; } //--- Constractor type2 --- 初期化問題あり★ Test(int a, int b) { a = a; b = b; } /* イニシャライザ使用 */ //--- Constractor type3 --- 初期化問題なし Test(int _a, int _b): a(_a), b(_b) {} //--- Constractor type4 --- 初期化問題なし(type2では問題あり) Test(int a, int b): a(a), b(b) {} };

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

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

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

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

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

guest

回答3

0

C++ の設計者である Bjarne Stroustrup 氏は型やスコープなどを変数名に埋め込むことに否定的です。 それが意味するところが名前に現れているべきであって、技術上の詳細を名前に埋め込むのは抽象度を下げる害悪だと述べています。 (部分的には便利な場合もあることは認めていますが。)

それをコンストラクタの仮引数の話にあてはめると、仮引数とデータメンバの名前が一致することはよくあることになるんじゃないでしょうか。 特に近年の高度なエディタ (統合開発環境) では識別子がどれと対応付いているかわかりやすい表示になっていたりもするので常にプレフィクスを付けたりするほどのことが必要だとは思いません。 個別の判断で誤解しやすさを避ける必要があると思ったときは何らかの対処をすればよいでしょう。

とはいえ、命名規則に関しては様々な方法論があり、そのどれかが他を圧倒するほど常識として確立しているというわけではありません。 各プロジェクトにおいて (明示的にせよ暗黙にせよ) 命名規則が定められているならそれに従うべきですし、自分に裁量権がある場合なら自分なりにわかりやすいやり方でやればよく、仮引数名のプレフィックスにアンダーバーを付けるくらいのことであれば自然なスタイルだと思います。


ちなみに以下のような識別子は言語仕様で予約されている (処理系の拡張などで使われることもある) ので使わないように気を付けましょう。

  • ふたつ以上のアンダーバーから始まる名前
  • アンダーバーで始まってそれに大文字が続く名前
  • アンダーバーから始まるグローバル変数名

投稿2020/09/29 22:44

SaitoAtsushi

総合スコア5714

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

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

Tteratail

2020/10/01 14:06

わざわざC++設計者のBjarne Stroustrup 氏の引用までありがとうございます(サイト自体勉強になりました)。読み手に誤解を生じないようなものであれば、近年の開発環境やStrousturp氏のコメントを考慮すればメンバ変数とコンストラクタの仮引数が同名で良いと理解しました。 予約語との兼ね合いで気を付けるべき命名についても情報ありがとうございます。参考になりました。
guest

0

ベストアンサー

1.メンバイニシャライザ(初期化子リスト)だと、コンストラクタの仮引数名がメンバ変数と同一でも問題なく初期化できいる?

  1. メンバイニシャライザを使わないと、コンストラクタの仮引数名がメンバ変数と同一だと正常に初期化できない?

要は,その名称を書いたときにそれがメンバなのか否かをはっきりさせればよい.
1.はそもそもメンバイニシャライザの文法的にどっちなのかが明確だから問題なし.
2.に関しては,こうすればOK.

C++

1Test(int a, int b) 2{ 3 this->a = a; 4 this->b = b; 5}

なので,メンバ変数と同一名称であることには特に問題がない.

  1. コンストラクタの仮引数の命名方法について常識やガイドラインはあるでしょうか?

「常識やガイドライン」の話ではないですが,
個人的には,メンバ変数の側を m_XXX と書く派なので,同一名称にならない.

投稿2020/09/29 15:41

編集2020/09/29 15:48
fana

総合スコア12194

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

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

Tteratail

2020/10/01 14:15

this->メンバ変数名とするか、イニシャライザ使えば、同名でも問題ないんですね。ありがとうございます。 m_XXXと書く派の方々もいるんですね。参考にさせて頂きます。
guest

0

コンストラクタで顕在化しやすいとは言えますが、別にコンストラクタがなにか特別なわけではなく、変数のスコープの問題なだけですね。

メンバイニシャライザを使わないと、コンストラクタの仮引数名がメンバ変数と同一だと正常に初期化できない?

一般に、スコープが異なって同じ名前の変数があったら、スコープが狭い方(後から宣言された方、と言っても同義か)が有効となります。メンバ変数と、メンバ関数(コンストラクタ)の仮引数やローカル変数が同名であれば、仮引数/ローカル変数としてアクセスすることになります。スコープの広い方がメンバ変数の場合は、this->変数名とすればアクセスは出来ますから、こちらでアクセスすれば「正常」でしょう。

コンストラクタの仮引数の命名方法について常識やガイドラインはあるでしょうか?

そんなにバリエーションがある話でもないのでは。

  • イニシャライザを使う
  • 仮引数の名前を変える

何らかのプリフィックス/サフィックスを付けるとか、短縮形/フルスペルにするとか

  • メンバ変数と同名にする

メンバ変数には、this->変数名 でアクセスする

決定的な優劣はないと思います。適切と思う方法を選べばよいのでは。
私は、敢えて変数名を重ねるのは気に入らないので(イニシャライザを使う場合でも)_を先頭につけることが多いですが(もちろん、大文字の前に_はダメです)。

同名で行けるんだから

同名ではダメだからこんな話になるのでしょう。

投稿2020/09/29 22:55

thkana

総合スコア7733

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

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

Tteratail

2020/10/01 14:12

変数のスコープについてコメントありがとうございます。私が挙げたダメだったケースではスコープ的に仮引数にアクセスしていただけだったんですね。this->メンバ変数名で正常にメンバ変数にアクセスできるとのこと、教えて頂きありがとうございます。頂いたコメント参考にして、今後は状況に応じて適切だと思う形式を使っていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問