クラスの宣言の仕方について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
pocket
記事: 49
登録日時: 8年前

クラスの宣言の仕方について

#1

投稿記事 by pocket » 7年前

お世話になっております.

C++暦は約2年になります.
ふと疑問に思ってソースコードを書いたところ,エラーが出ました.
その原因についてお教えいただければ幸いです.

コード:

#include <random>
#include <iostream>
using namespace std;

class Sample{
  public:
    Sample(int rand):menber(rand){};
    
    int getRand();
    int menber;   
};
int Sample::getRand(){
    std::random_device rand;
    return(rand()%100);   
}

int main(){
    //Sample sampleA;
    //sampleA=Sample(sampleA.getRand());
    Sample sampleA = Sample(sampleA.getRand());     
    cout<<sampleA.menber<<endl;
}
一行でクラスの宣言をした場合は,適切に動作しますが,
二行に分けた場合(ソースコード内でコメントしている部分)は,エラーが出ます.

実行環境のリンクを載せます.
http://melpon.org/wandbox/permlink/QJonnkRMCRN8cgZH

new演算子で試してみてもうまく動作しませんでした.
解決策を,この問題が起こる原因について解答いただければと思います.
よろしくお願いいたします.
よろしくお願いいたします.

Rittai_3D
記事: 525
登録日時: 11年前

Re: クラスの宣言の仕方について

#2

投稿記事 by Rittai_3D » 7年前

デフォルコトンストラクタを追加したら動きました。

コード:

#include <random>
#include <iostream>
using namespace std;

class Sample{
  public:
    Sample() = default;
    Sample(int rand):menber(rand){};

    int getRand();
    int menber;   
};
int Sample::getRand(){
    std::random_device rand;
    return(rand()%100);   
}

int main(){
    Sample sampleA;
    sampleA=Sample(sampleA.getRand());
    //Sample sampleA = Sample(sampleA.getRand());     
    cout<<sampleA.menber<<endl;
}
http://melpon.org/wandbox/permlink/6pDDH3CkAUx2GADk
初心者です

C6b14

Re: クラスの宣言の仕方について

#3

投稿記事 by C6b14 » 7年前

参考までに。想像ですが、こういう事をされたかったのではないですか。

コード:

#include <random>
#include <iostream>
using namespace std;

class Sample {

public:
	Sample() :menber(123) {}//コンストラクター:イニシャライザ
	
	int getRand();//getメソッド
	//int menber;
private:
	std::random_device rand;//rand=乱数生成器
	int menber;//メンバー変数
};
int Sample::getRand() {//getメソッド
	menber = rand();
	return(menber % 100);
}

int main() {
	Sample *sampleA;//宣言
	sampleA = new Sample();//インスタンス生成
	//Sample *sampleA = new Sample();

	cout << sampleA->getRand() << endl;
}
なぜイニシャライザがいるのか?

アバター
usao
記事: 1887
登録日時: 11年前

Re: クラスの宣言の仕方について

#4

投稿記事 by usao » 7年前

オフトピック
>Sample sampleA = Sample(sampleA.getRand());

どちらかというと,こっちの書き方が気になる.
getRand()呼ぶ時点では,インスタンスsampleAは生成されていないように見えるのだけど…

あんどーなつ
記事: 171
登録日時: 7年前
連絡を取る:

Re: クラスの宣言の仕方について

#5

投稿記事 by あんどーなつ » 7年前

pocket さんが書きました:お世話になっております.
C++暦は約2年になります.
ふと疑問に思ってソースコードを書いたところ,エラーが出ました.
その原因についてお教えいただければ幸いです.
宜しければその疑問も聞かせていただけますか?

Sample sampleA; がダメな理由ですが、これは、
Sample sampleA(); や Sample sampleA{}; と同じ意味だからです。つまり、この引数を宣言してからmain関数が終わるまでの寿命を持つSample型のオブジェクトを引数なしで生成しているためです。

クラスにコンストラクタを記述しなかった場合は、デフォルトコンストラクタが生成されるので、Sample sampleA; はOKとなりますが、引数が異なるコンストラクタを定義しているので、デフォルトコンストラクタが生成されず、Sample sampleA;がNGとなっています。

Sample *sampleA = new Sample(sampleA.getRand()); でもOKです。ただしこの場合はmain関数の最後にdelete sampleA; と書く必要があります(今回の場合は本当は書かなくてもよいのですが、書かないとトイレの戸を開けっ放しにしているように思われるからnewといえばdeleteを心がけましょう)。

pocket
記事: 49
登録日時: 8年前

Re: クラスの宣言の仕方について

#6

投稿記事 by pocket » 7年前

みなさん

複数の返答ありがとうございます.
疑問点とは,usaoさんがおっしゃっていることについてです.

私が見たプログラムで,以下のように,定義した変数(sampleA)自身の関数(getRand)を自分の引数(コンストラクタ)に使っていたので,実際に動作するかの検証をしたかったです.

コード:

Sample sampleA = Sample(sampleA.getRand());  
あんどーなつさんのおっしゃることを参考に,今回の問題と原因をまとめたいと思います.
まず,自身でint引数をとるコンストラクタを新しく作成した場合は,デフォルトコンストラクタが作成されないため,
Sample sampleA;の部分でエラーが出ていました.この文でデフォルトコンストラクタ(引数なしコンストラクタ)を呼ぶためです.
なので,デフォルトコンストラクタを明示的に作成することで解決しました.
(デフォルトコンストラクタをSample() = default;の様に書けるのですね.初めて知りました.)

私の疑問点についてお時間を割いていただき,本当にありがとうございました.
以上で,解決とさせていただきます.

閉鎖

“C言語何でも質問掲示板” へ戻る