Menu
Coddy logo textTech

引数付きコンストラクタ

CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 19/104。

引数付きコンストラクタは、生成時に特定の値でオブジェクトを初期化できるように引数を受け取ります。デフォルト値に頼るのではなく、各オブジェクトの初期状態をカスタマイズすることができます。

class Player {
    std::string name;
    int health;
    int level;
public:
    Player(std::string n, int h, int lvl) {
        name = n;
        health = h;
        level = lvl;
    }
};

Player hero("Archer", 100, 5);
Player mage("Wizard", 80, 7);

異なるパラメータリストを持つ複数の引数付きコンストラクタを定義できます。これはコンストラクタのオーバーロードと呼ばれ、コンパイラは提供された引数に基づいて適切なものを選択します。

class Rectangle {
    int width, height;
public:
    Rectangle(int side) {          // 正方形
        width = height = side;
    }
    
    Rectangle(int w, int h) {      // 長方形
        width = w;
        height = h;
    }
};

Rectangle square(10);        // 最初のコンストラクタを呼び出す
Rectangle rect(10, 20);      // 2番目のコンストラクタを呼び出す

パラメータにはデフォルト値を持たせることができ、一部の引数をオプションにすることが可能です。これにより、複数のオーバーロードされたコンストラクタを用意する必要性が減ります。

class Enemy {
    std::string type;
    int damage;
public:
    Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};

Enemy goblin("Goblin");       // damage のデフォルト値は 10 です
Enemy dragon("Dragon", 50);   // damage は 50 に設定されます

前のレッスンの内容を思い出しましょう。引数付きコンストラクタを一度定義すると、コンパイラはデフォルトコンストラクタを自動的に生成しなくなります。両方が必要な場合は、デフォルトコンストラクタを明示的に定義する必要があります。

challenge icon

チャレンジ

簡単

引数付きコンストラクタを使用して特定の初期値を持つオブジェクトを作成する方法と、コンストラクタのオーバーロードによってオブジェクト作成に柔軟性を持たせる方法を学ぶために、製品在庫システムを構築しましょう。

コードを整理するために、2つのファイルを作成します。

  • Product.h: 在庫内のアイテムを表す Product クラスを定義します。クラスには以下を含める必要があります:
    • name (string)、price (double)、quantity (integer) のためのプライベート属性
    • 製品を完全に初期化するために、3つすべてのパラメータ (name, price, quantity) を受け取るコンストラクタ
    • name と price のみを受け取り、quantity のデフォルト値を 1 とするコンストラクタ
    • name のみを受け取り、price のデフォルト値を 0.0、quantity のデフォルト値を 0 とするコンストラクタ
    • 製品情報を "<name>: "<name>: $<price> (x<quantity>)"lt;price> (x<quantity>)" の形式で出力する display() メソッド
    • price に quantity を掛けた値を返す getTotalValue() メソッド
  • main.cpp: 入力を読み取り、異なる方法で製品を作成することで、3つすべてのコンストラクタを実演します。入力から以下を読み取ります:
    • 1行目:製品名、価格、数量(スペース区切り)
    • 2行目:製品名、価格(スペース区切り)
    • 3行目:製品名のみ
    各入力に対して適切なコンストラクタを使用して3つの Product オブジェクトを作成し、それぞれに対して display() を呼び出します。その後、3つの製品すべての合計金額を "Total inventory value: "Total inventory value: $<value>"lt;value>" の形式で出力してください。

価格の出力については、小数点以下1桁で表示してください。例えば、価格 999.99、数量 5 の製品 "Laptop" を作成した場合、表示は "Laptop: $999.99 (x5)" となる必要があります。

main.cpp で #include "Product.h" を使用してヘッダーファイルをインクルードしてください。

チートシート

引数付きコンストラクタは、オブジェクトの生成時に特定の値で初期化するために引数を受け取ります:

class Player {
    std::string name;
    int health;
    int level;
public:
    Player(std::string n, int h, int lvl) {
        name = n;
        health = h;
        level = lvl;
    }
};

Player hero("Archer", 100, 5);

コンストラクタのオーバーロードにより、異なる引数リストを持つ複数のコンストラクタを定義できます:

class Rectangle {
    int width, height;
public:
    Rectangle(int side) {          // 正方形
        width = height = side;
    }
    
    Rectangle(int w, int h) {      // 長方形
        width = w;
        height = h;
    }
};

Rectangle square(10);        // 最初のコンストラクタを呼び出す
Rectangle rect(10, 20);      // 2番目のコンストラクタを呼び出す

デフォルト引数を使用すると、引数を省略可能にできます:

class Enemy {
    std::string type;
    int damage;
public:
    Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};

Enemy goblin("Goblin");       // damageはデフォルトで10になる
Enemy dragon("Dragon", 50);   // damageは50に設定される

引数付きコンストラクタを定義すると、コンパイラはデフォルトコンストラクタを自動的に生成しなくなります。

自分で試してみよう

#include <iostream>
#include <iomanip>
#include <string>
#include "Product.h"

using namespace std;

int main() {
    // 1つ目の製品を読み込む:名前、価格、数量
    string name1;
    double price1;
    int quantity1;
    cin >> name1 >> price1 >> quantity1;
    
    // 2つ目の製品を読み込む:名前と価格
    string name2;
    double price2;
    cin >> name2 >> price2;
    
    // 3つ目の製品を読み込む:名前のみ
    string name3;
    cin >> name3;
    
    // TODO: それぞれに適切なコンストラクタを使用して、3つの Product オブジェクトを作成する
    
    // TODO: 各製品に対して display() を呼び出す
    
    // TODO: 在庫の総額を計算して表示する
    // フォーマット: "Total inventory value: $<value>"
    // 小数点以下1桁を表示するために fixed と setprecision(1) を使用する
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン