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

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

新規登録して質問してみよう
ただいま回答率
85.48%
コンストラクタ

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

C++

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

Q&A

解決済

3回答

325閲覧

コンストラクタについて

退会済みユーザー

退会済みユーザー

総合スコア0

コンストラクタ

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

C++

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

0グッド

0クリップ

投稿2017/09/14 14:55

編集2017/09/14 14:59

C++

1#include <memory> 2 3using namespace std; 4 5class MyClass { 6public: 7 ~MyClass() {}; 8 MyClass * GetMyClass(bool var); 9private: 10 MyClass() {}; 11}; 12 13MyClass::MyClass * GetMyClass(bool var) { 14 return (var) ? new * MyClass : 0; 15} 16 17int main() { 18 auto_ptr<MyClass> mc = GetMyClass(true); 19 20 return 0; 21}

###質問
上記ソースコードで、GetMyClass()をコール、trueの場合にコンスラクタをコール、インスタンスを取得していますが、
GetMyClass()をコールした時点でMyClassを使用する為、コンストラクタが実行されるのではないのでしょうか?

###補足情報(言語/FW/ツール等のバージョンなど)
C++について勉強中の為、上記ソースコードに文法エラー等がありましたら申し訳ありません。
ご教授、お願いいたします。

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

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

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

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

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

can110

2017/09/14 15:03

提示コードはideone.comのC++14環境ではコンパイルエラーが発生しました。まずはコンパイル可能なコードを提示しないと回答得られにくいと思われます。
退会済みユーザー

退会済みユーザー

2017/09/14 15:10

can110さん ご指摘ありがとうございます。週末にコンパイルが通るものを再投稿いたします。
can110

2017/09/14 15:14

まずはLouiS0616さんの回答を確認された後でよいかと思います。
退会済みユーザー

退会済みユーザー

2017/09/14 15:21

can110さん サンプルコードを追い、理解を深めようと思います。
can110

2017/09/14 15:25

たとえばhttps://ideone.com/などのオンライン実行環境でコンパイル~実行が簡単にできます。お試しあれ。
退会済みユーザー

退会済みユーザー

2017/09/14 22:52 編集

can110さん ideoneを試してみました。外出中にコンパイルが通るかどうか、簡単な記述ミス等のチェックに使いたいと思います。 ありがとうございます。
guest

回答3

0

こんにちは。

GetMyClass()をコールした時点でMyClassを使用する為、コンストラクタが実行されるのではないのでしょうか?

文法エラーがあるのではっきりしませんので一旦文法エラーを取りました。(あと、非推奨のauto_ptrをunique_ptrへ変更してます。)

C++

1#include <memory> 2 3using namespace std; 4 5class MyClass 6{ 7public: 8 ~MyClass() {}; 9 static MyClass* GetMyClass(bool var) 10 { 11 return (var) ? new MyClass : 0; 12 } 13private: 14 MyClass() {}; 15}; 16 17int main() 18{ 19 unique_ptr<MyClass> mc(MyClass::GetMyClass(true)); 20 21 return 0; 22}

上記について回答します。
GetMyClass()でMyClassへのポインタを返却させようとした時点でMyClassがコンストラクトされるのではないか?との疑問でしょうか?

まず、ポインタはnullptrも許されることからも分かると思いますが、インスタンスを必要とするわけではありません。つまり、nullptrを返却する可能性もあるのでGetMyClass()呼び出しの時点ではコンストラクトされません。

また、C++の文法上では、戻り値はreturn文で生成されます。つまり、ポインタではなくインスタンスを返却するような場合でも、呼び出した時点でコンストラクトされるのではなく、return文実行時にコンストラクトされます。なお、実際には最適化によりもっと効率は良い場合が多いので、インスタンスの返却をあまり恐れなくてよいです。

それから、元のソースではGetMyClass()は非static関数でした。この場合、GetMyClass()を呼ぶにはMyClassのインスタンスが必要になります。意味が無いので、そのような使い方はあまりしないと思います。

投稿2017/09/14 15:23

Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2017/09/17 14:08

Chironianさん 常々ありがとうございます。 今回、私が特に聞きたかった内容を回答でした。 必ずしもインスタンスは必要ではないことと、staticである必要性を理解いたしました。
退会済みユーザー

退会済みユーザー

2017/09/17 14:17

Chironianさん 本件とは別の質問になるのですが、 今回、私が聞きたい内容をズバリ回答頂き驚いております。 質問を読み解くコツ等は御座いますでしょうか?
Chironian

2017/09/17 15:05

たぶん私も昔似たような疑問を感じたことがあるからだと思います。その時は参照だったと思います。
guest

0

はい。クラスに属するインスタンス生成をnew演算子で実行しているので、コンストラクタが呼び出されます。

が、当該コードは少し特別なものです。また、多分コンパイル通りません(未確認)。おそらく、当該コードはSingletonと呼ばれるデザインパターンのものを意図したものでしょう。ご覧の通り、このコンストラクタの中身がありません。つまり、「インスタンス生成時にコンストラクタが呼び出される」ということはここでは重要ではありません。

このコンストラクタの重要なところはprivateメソッドであることです。これはクラスの外部において、当該インスタンスのnewを文法レベルで禁止する記法となります。従って、クラス外部から可能なことはstaticフィールド、staticメソッドへのアクセスのみとなります。つまり、getMyClassメソッドはstaticでなければなりません。

なお、Singletonクラスは性質上、インスタンス生成時に必ずそのクラスのstaticメソッドを経由することになります。このため、インスタンス生成に大きな制約を作ることができ、管理を用意とすることが趣旨とされています。(名前の通り、インスタンスを一つしか作らせないように使うことが多い。例えば、ハードウェアと直結するようなインスタンスについては複数存在する意味がないため)

投稿2017/09/14 15:02

編集2017/09/14 15:20
HogeAnimalLover

総合スコア4830

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

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

退会済みユーザー

退会済みユーザー

2017/09/14 15:09

HogeAnimalLoverさん 回答ありがとうございます。 GetMyClass()コール時にインスタンス生成でしょうか? GetMyClass()内でtrueの場合のみ、インスタンス生成でしょうか? 申し訳ありません、週末にコンパイルが通るものを再投稿したいと思います。 ご指摘ありがとうございます。
退会済みユーザー

退会済みユーザー

2017/09/17 13:56

HogeAnimalLoverさん Singletonのデザインパターンを理解しました。 staticなメンバ変数が存在しないのでSingletonとは異なるようですが 構成自体は似ていますね。 今回、初めてSingletonといった言葉を知ることが出来ました。 ありがとうございました。
guest

0

ベストアンサー

これで実験してみましょう。

C++

1#include <iostream> 2#include <memory> 3 4class MyClass { 5 public: 6 ~MyClass(void) { 7 std::cout << "destructor" << std::endl; 8 } 9 static MyClass * getMyClass(bool) { 10 std::cout << "getMyClass" << std::endl; 11 return new MyClass; 12 } 13 14 void hogehoge(void) { 15 std::cout << "hogehoge" << std::endl; 16 } 17 18 private: 19 MyClass(void) { 20 std::cout << "constructor" << std::endl; 21 } 22}; 23 24int main(void) { 25 std::unique_ptr<MyClass> mc(MyClass::getMyClass(true)); 26 mc->hogehoge(); 27 return 0; 28}

出力

getMyClass constructor hogehoge destructor

ご提示のコードには問題があります。

  • getMyClassがstaticでないこと
  • 非推奨であるauto_ptrを用いていること(C++11なら別ですが)

投稿2017/09/14 15:04

編集2017/09/14 15:08
LouiS0616

総合スコア35660

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

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

退会済みユーザー

退会済みユーザー

2017/09/14 15:17

LouiS0616さん 回答ありがとうございます。 サンプルを提供していただきありがとうございます。 週末にVS環境を使用してサンプルコードを追っていきたいと思います。 また、問題指摘していただきました、staticメンバ関数を使用しなければコンパイルが通らない理由も調べようと思います。 大変参考になりました、ありがとうございます。
退会済みユーザー

退会済みユーザー

2017/09/17 13:56 編集

LouiS0616さん VSでコードを追ってみました。 素晴らしいサンプルを提供頂いたため、スムーズに理解とイメージを身に付けることが出来ました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問