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

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

ただいまの
回答率

88.80%

クラスのコンストラクタ

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 395

hikar

score 13

#include <iostream>

struct Rect {
    float m_position;
    float m_size;

    Rect(float const& _position, float const& _size);
    void Draw();
};

Rect::Rect(float const& _position, float const& _size)
:m_position(_position)
, m_size(_size)
{}

void Rect::Draw() {
    std::cout << m_position << std::endl;
    std::cout << m_size << std::endl;
}

Rect rect=Rect(100, 200);
/***********デバックエラー
Rect rect;
rect.Rect(100, 200);
**************************/
int main() {

    rect.Draw();

    return 0;
}


確認というかたちになってしまうかもしれませんが、
上のソースコード「Rect rect=Rect(100, 200);」の部分なのですが、
これは、構造体Rect(基底クラス?)を rect(派生クラス?)に引き継ぎ、rect=Rect(100,200)で初期化(代入)。ということでしょうか?私は
Rect rect;
rect.Rect(100, 200);
でやろうとしたのですが、エラーが出てしまいました。

Rect(float const& _position, float const& _size)
:m_position(_position)
, m_size(_size)

これは基底クラスのコンストラクタであって、派生クラスではつかえないということでしょうか?
このような考え方であっているのであれば、rect=Rect(100,200)の仕様がよくわかりません。
派生クラス内のコンストラクタはどのようになっているのでしょうか?
基底クラスと中身は同じで、rect内は

struct rect {
    float m_position;
    float m_size;

    Rect(float const& _position, float const& _size);
    void Draw();
};


このようになっているのでしょうか?
そして構造体rect(派生)とコンストラクタRectの型が合わずエラーが起きてしまう。
なので上記のようにrect=Rect(100,200)でrectクラス(派生)のRectに代入しているのでしょうか?
まったくの的外れだったらすみません。<(_ _)>

それとちなみに

Rect(float const& _position, float const& _size)
:m_position(_position)
, m_size(_size)

ここで使っている「&」はネットで調べたら、参照渡しとわかりましたが、これは今後必要なのでしょうか?

「&」:元の変数に別名をつける記法である(ここで使うの場合)

「&」がなくても引数の名前は変えられる気がしますが.....
「&」がなくてもデバック結果は変わりませんでした。

的外れのことを書いていたらすみません。<(_ _)>
どなたかわかる方どうか教えてください<(_ _)>

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

クラスは型です。
ここでは Rect は型であり、その型を元に生成されたオブジェクトを入れる場所が rect です。

そして

Rect rect;

がエラーになるのはデフォルトコンストラクタが定義されていないからです。 デフォルトコンストラクタというのは引数がないコンストラクタです。 変数宣言のときに引数を渡さなければデフォルトコンストラクタで処理しようとします。 しかし呼び出すべきものがないのでエラーになります。 (自分でコンストラクタをひとつも定義しなければデフォルトコンストラクタは自動生成されます。)

rect=Rect(100,200)の仕様がよくわかりません。

クラスは型だと説明しましたが、 C++ のクラス名は常にそのクラスのコンストラクタと同じ名前を持ちます。 Rect(100,200) は Rect 型のオブジェクトを生成する関数を呼び出していると考えてください。

Rect rect という宣言によって Rect 型の変数 rect が用意され、 Rect(100,200) という関数を呼び出した結果を rect に入れるという意味になっています。

rect に Rect(100,200) を入れるにあたってはコピーコンストラクタが呼ばれていて、これも自分で書かなければ自動生成されています。

参照渡しとわかりましたが、これは今後必要なのでしょうか?

はい。 絶対に必要です。

「&」がなくても引数の名前は変えられる気がしますが.....
「&」がなくてもデバック結果は変わりませんでした。

この場所で & を付けなかった場合、引数を渡した側の「コピー」になります。 同じものを別の名前で見るというのと、同じ内容のものがふたつあるというのとでは違うので使い分けが必要です。 必要もないのにコピーするのは実行速度も遅くなる可能性があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/04 18:22

    ご返答ありがとうございました。とても分かりやすかったです。!(^^)!
    クラス内でコンストラクタを意図的に宣言しない場合はオブジェクト生成時にデフォルトコンストラクタが自動で生成されるが、
    上のように自分で意図的にコンストラクタをクラス型内で定義した場合は、Rect rect;では自動的にコンストラクタが生成されないため、オブジェクト生成時に一緒にコンストラクタされるはずが、その元のコンストラクタがないてめ、エラーになってしまう。だから、Rect rect=Rect(100, 200);でオブジェクト生成時に意図的にコンストラクタを生成しなければならないということでよろしいでしょうか?
    そして、ここでのコンストラクタはクラス内の変数に初期値を設定してオブジェクトを生成というつかいかたでよろしいでしょうか?
    ちなみにに、クラス内でデフォルトコンストラクタを定義した場合は、
    Rect rect;
    Rect();
    これでできる。ということでしょうか?
    (クラス内で定義しなくても、オブジェクト生成時に自動で生成されるから定義しなくてもいい?)
    いただいた返答からこのように考えたのですが、間違えていたら嫌なので、確認で再度質問投稿になってしまうのですが、どうかよろしくお願いします。<(_ _)>

    キャンセル

  • 2020/02/04 19:55

    関連する事柄が多いので全てをここで述べることはできません。 しかし、基礎なのでどんな入門書を読んでも理解できるように書いてあるはずです。 (もし書いていないなら単に出来の悪い教材です。)

    大雑把には回答しますが、細かいことはきちんとした資料を読んでください。

    > オブジェクト生成時にデフォルトコンストラクタが自動で生成される

    いいえ。 デフォルトコンストラクタはクラス定義時に暗黙に定義されたかように振舞います。 オブジェクト生成時にそれが「起動」します。

    > Rect rect=Rect(100, 200);でオブジェクト生成時に意図的にコンストラクタを生成しなければ

    コンストラクタを起動して出来上がったオブジェクトを rect にコピーするということが起こっています。
    Rect rect(100, 200); という書き方でも良いです。
    こちらの書き方では生成してからコピーではなく、 rect の場所で 100 と 200 という引数と共にコンストラクタが起動するという形です。 rect の場所で直接的にコンストラクタが起動するので少し効率がよいかもしれません。

    ただし、一部の状況ではコピーを抑制する最適化をしてもよいという仕様があり、 Rect rect=Rect(100, 200); を Rect rect(100, 200); と同じように解釈することがあります。 (従来はそのような最適化を許容する仕様でしたが、最新仕様では必須の挙動に変更されています。)

    > ここでのコンストラクタはクラス内の変数に初期値を設定してオブジェクトを生成というつかいかたでよろしいでしょうか?

    それでよいですが、定義するクラスの役割によっては初期値を設定する以外のことをすることもあります。

    > 自動で生成されるから定義しなくてもいい?

    自動で生成されるコンストラクタは一定のルールに則って処理するだけなので、クラスの性質によっては問題が生じることもあります。 自動生成されるコンストラクタで良いかどうかを判断するのはあなた次第です。

    キャンセル

  • 2020/02/05 04:32

    ご返信ありがとうございました(>_<)
    すごくわかりやすく、完全に理解出来ました!
    またわからないことがあったら質問させていただきますので、よろしくお願いします。<(_ _)>

    キャンセル

+1

これは、構造体Rect(基底クラス?)を rect(派生クラス?)に引き継ぎ、rect=Rect(100,200)で初期化(代入)。ということでしょうか?私は
Rect rect;
rect.Rect(100, 200);
でやろうとしたのですが、エラーが出てしまいました。

このやり方ではデフォルトコンストラクタがないので、出来ません。
やりたいならポインターを使ってnewするのが良いでしょう。

Rect *rect;
rect = new Rect(100, 200);

このようになっているのでしょうか?

float a;
a = .0f;

この場合、float型の変数「a」となります。同様にRect型の変数「rect」となります。
ですので、構造体もクラスも変数もインスタンスするという意味では同じ考え方になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/05 04:39

    ご返信ありがとうございます。(>_<)
    教えていただいたコードで正常に実行することができました。
    newについてあまりよく調べてないので、これからしっかり勉強していきます。
    またわからないことがあったら質問させていただきますので、よろしくお願いします。

    キャンセル

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

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る