🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。

C++

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

Q&A

4回答

2353閲覧

コンストラクタがデフォルトコンストラクタとして機能する条件を詳しく知りたい

退会済みユーザー

退会済みユーザー

総合スコア0

コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。

C++

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

0グッド

3クリップ

投稿2021/03/16 07:44

最近、コンストラクタ・デストラクタについて

  • デフォルトコンストラクタとは実引数の指定が不要なコンストラクタのこと
  • デフォルトコンストラクタを定義しないと、空のデフォルトコンストラクタがコンパイラによって生成されること
  • 仮引数を持つコンストラクタがあると、デフォルトコンストラクタを自身で定義しなければならないこと

の以上3点を学びました。

コンストラクタ・デストラクタを用いて、プログラムの実行時間を表示するクラス(?)を作ってみたのですが、このクラス(下記参照)は仮引数を持つコンストラクタがあるにもかかわらず、デフォルトコンストラクタを自身で定義しなくとも、問題なくコンパイル(g++)・実行できてしまいました。


質問:
この場合、measure(option flag) {...} がこのクラス(?)のデフォルトコンストラクタとして扱われていると考えてよいのでしょうか。
仮にその場合、実引数の指定があるにもかかわらず、何故measure(option flag) {...} がデフォルトコンストラクタとして扱われているのでしょうか。
私はプログラミング初心者なので、記法をはじめとして、このコードに対する指摘・アドバイスなどあればそれも併せて教えていただけると幸いです。
よろしくお願いします。


C++

1#include <iostream> 2#include <chrono> 3 4namespace function { 5 enum option : bool { 6 able = true, 7 disable = false 8 }; 9 struct measure { 10 measure(option flag) { 11 _flag = flag; 12 if(flag) { 13 start = std::chrono::steady_clock::now(); 14 } 15 } 16 ~measure() { 17 if(_flag) { 18 end = std::chrono::steady_clock::now(); 19 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); 20 std::cout << "\ntime: " << elapsed.count() << " ms" << std::endl; 21 } 22 } 23 private: 24 option _flag; 25 std::chrono::steady_clock::time_point start, end; 26 std::chrono::milliseconds elapsed; 27 }; 28} 29 30int main() { 31 function::measure(function::able); 32 // action 33 return 0; 34}

Output

1 2time: 0 ms

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

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

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

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

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

y_waiwai

2021/03/16 07:56

> デフォルトコンストラクタを定義しないと、空のデフォルトコンストラクタがコンパイラによって生成されること ってだけのはなしでは
Y.H.

2021/03/16 10:12

最近こんな質問者ばかりだなぁ。
guest

回答4

0

この場合、measure(option flag) {...} がこのクラス(?)のデフォルトコンストラクタとして扱われていると考えてよいのでしょうか。

いいえ。measure(option flag)コンストラクタはoption型の引数を1つとりますから、これはデフォルトコンストラクタではありません。

仮にその場合、実引数の指定があるにもかかわらず、何故measure(option flag) {...} がデフォルトコンストラクタとして扱われているのでしょうか。

(前提条件が偽のため、この質問はスキップします)


記法をはじめとして、このコードに対する指摘・アドバイス

main関数が意図通りに実装されていません。質問中にあるコードでは「function::measureクラスに値function::ableを指定して一時オブジェクトを構築し、同一行内でそのオブジェクトを破棄」してしまいます。つまりコード区間の時間計測としては全く機能せず、常に0 msと出力されるはずです。

訂正:Most Vexing Parse(の複雑なケース)に該当します。構文的にはfunction::measure型の変数function::able宣言と解釈されますが、これは意味論(セマンティクス)上は不正な宣言となるためコンパイルエラーとみなされます。StackOverfloaのMost vexing parse with a qualified-id - or not?Is Type(::x); valid?もご参考に。

cpp

1int main() { 2 function::measure(function::able); 3 // (計測対象の処理) 4}

本来の意図は、下記のコード実装ではないでしょうか。

cpp

1int main() { 2 function::measure span(function::able); // オブジェクト作成=計測開始 3 // (計測対象の処理) 4} // ここでオブジェクトが破棄される=計測終了

また、全般的に名前付けルールが少々気になりました。

  • 名前空間functionは、C++標準ライブラリのstd::function<R(Args..)>テンプレートクラスと名前が被りますし、「機能(function)」という名前空間では意味が抽象的すぎる気がします。
  • 列挙型optionの列挙子able,disableも、それぞれ名前が抽象的すぎて具体的な機能を連想しづらいです。(ableenableのニュアンス?)

投稿2021/03/16 08:14

編集2021/03/16 15:34
yohhoy

総合スコア6191

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

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

退会済みユーザー

退会済みユーザー

2021/03/16 08:44

コード実装の件、確かにそうですね。訂正しておきます。 functionではなくMyFuncとかにしておけば良いですかね...?
yohhoy

2021/03/16 08:48

名前付けに正解はありませんので、他にどんなクラスや関数を含めたいか次第だと思います。 もちろん MyFunc でもよいですし、timer や util や misc などでも。
guest

0

この場合、measure(option flag) {...} がこのクラス(?)のデフォルトコンストラクタとして扱われていると考えてよいのでしょうか。

違います。デフォルトコンストラクタはこのコードに登場しません(引数のあるコンストラクタしか呼んでいないので、デフォルトコンストラクタは関係しません)。

投稿2021/03/16 08:09

maisumakun

総合スコア145971

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

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

maisumakun

2021/03/16 08:11

デフォルトコンストラクのないクラスは「引数なしで初期化できない」だけで、存在しても全く問題ありません(用法によってはあえて作ることもありえます)。
maisumakun

2021/03/16 08:14

> 仮引数を持つコンストラクタがあると、デフォルトコンストラクタを自身で定義しなければならないこと 「デフォルトコンストラクタが必要なら」自分で書かないといけない、です。
guest

0

デフォルトコンストラクタとは実引数の指定が不要なコンストラクタのこと

Yes.そのとおり。

デフォルトコンストラクタを定義しないと、空のデフォルトコンストラクタがコンパイラによって生成されること

No.何かしらのコンストラクタ(引数ありでも可)を定義すれば、デフォルトコンストラクタは自動生成されなくなる。

仮引数を持つコンストラクタがあると、デフォルトコンストラクタを自身で定義しなければならないこと

No.不要

投稿2021/03/17 03:02

HogeAnimalLover

総合スコア4830

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

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

0

実引数の概念に対して勘違いがありました。

C++

1#include <iostream> 2#include <cstdint> 3 4struct display{ 5 display(int64_t x) { 6 std::cout << x << "\n" << std::flush; 7 } 8}; 9 10int main(){ 11 int64_t n = 16; 12 display(n); 13 return 0; 14}

この場合は実引数nの存在により、デフォルトコンストラクタの定義が必要ですが、

C++

1#include <iostream> 2#include <cstdint> 3 4struct display{ 5 display(int64_t x) { 6 std::cout << x << "\n" << std::flush; 7 } 8}; 9 10int main(){ 11 display(16); 12 return 0; 13}

この場合は16は実引数に値せず、display(int64_t x) {...}がデフォルトコンストラクタとして扱われるこういうことだったのですね。

(追記: どうやらこれも違うようですね。勉強不足で申し訳ない...。)

投稿2021/03/16 08:21

編集2021/03/16 08:50
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yohhoy

2021/03/16 08:25 編集

デフォルトコンストラクタについて盛大に誤解されているような印象を受けます... 「16は実引数に値」します。 「display(int64_t x) {...}がデフォルトコンストラクタとして扱われ」ません。
退会済みユーザー

退会済みユーザー

2021/03/16 08:32

visual studio code では、一つ目のコードは「クラス "display" の既定のコンストラクターは存在しません」となり、コンパイルできないのですが、二つ目のコードは問題なく実行できたんです...。 この違いは何なのでしょうか...。
maisumakun

2021/03/16 08:40 編集

display(n);だけでは、display n;として解釈されます。この形なら、デフォルトコンストラクタを呼ぶのは明らかかと思います。
yumetodo

2021/03/16 08:43

clangにコンパイルさせてみると原因ははっきりするように思えます。()が余計で display n; と書いたかのように振る舞おうとします。しかしながら、 1. displayクラスにdefault ctorがない 2. 変数nが再定義されている という理由からエラーになっています。 https://wandbox.org/permlink/K6jDTCzWbk9rbMvZ
maisumakun

2021/03/16 08:43

> この場合は実引数nの存在により、デフォルトコンストラクタの定義が必要ですが 正反対です。nが実引数として「解釈されない」からデフォルトコンストラクタが呼ばれます。
yumetodo

2021/03/16 08:51

()の挙動ってなんかC++20だかで変わらなかったっけ(あやふや こわいので{}を使いたい。
yohhoy

2021/03/16 23:47 編集

C++20で丸括弧()の意味論が変わってはいないはず... 波括弧{}であればこんな挙動とならないのはその通りですね;P
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問