C++ でクラスコンストラクタを実装する

胡金庫 2023年10月12日
  1. コンストラクターとは何か、C++ でどのように機能するか
  2. C++ でオーバーロードを使用して複数のクラスコンストラクターを実装する
C++ でクラスコンストラクタを実装する

この記事では、C++ でクラスコンストラクターを実装する方法を紹介します。

コンストラクターとは何か、C++ でどのように機能するか

コンストラクターは、クラスオブジェクトの初期化方法を定義する特別なメンバー関数です。コンストラクターは通常、クラスのデータメンバーを初期化し、クラスオブジェクトの作成時に実行されます。コンストラクター関数のいくつかの特定の機能は、それらがクラス自体と同じ名前を持ち、戻り型を持つことができないことです。通常、クラスには相互にオーバーロードする複数のコンストラクターがありますが、パラメーターの数またはタイプが異なる必要があります。

コンストラクターは、少し複雑なクラスでユーザーによって明示的に指定されることが多いことに注意してください。それでも、ユーザーがコンストラクターを定義しない場合、デフォルトのコンストラクターはコンパイラーによって自動的に生成されます。デフォルトのコンストラクターは通常、引数をとらないコンストラクターであり、クラスのデフォルトの初期化のために呼び出されます。ただし、コンパイラによって生成されたデフォルトコンストラクタは、正式には合成デフォルトコンストラクタと呼ばれることに注意してください。後者は、データメンバーに従ってクラスごとに具体的に推測され、クラス内初期化子またはデフォルト値を使用してメンバーを初期化します。したがって、自動生成されたコンストラクターは普遍的なソリューションではありませんが、単純なクラス構造では正しく機能します。

次の例では、2つのコンストラクターを使用して MyClass1 クラスを定義しました。最初のものは引数を取らないことに注意してください。これは、それがデフォルトのコンストラクターであることを意味しますが、それでも default キーワードを指定しました。後者は、この特定のコンストラクターをデフォルトのコンストラクターにする必要があることをコンパイラーに示します。一般に、ユーザーがコンストラクターを定義した場合、コンパイラーはデフォルトのコンストラクターを生成しません。この場合、ユーザーは、指定されたコンストラクター関数の default 指定を明示的に要求する必要があります。

MyClass1 の 2 番目のコンストラクターは、引数として単一の string 値を取り、それを使用して name データメンバーを初期化します。特別な文字列リテラルを cout ストリームに出力して、関数の実行瞬間を観察できるようにします。m2 オブジェクトの作成により、コンストラクターがトリガーされます。m1 オブジェクトはデフォルトのコンストラクターで初期化され、コンパイラー自体が後者のコンストラクターを生成するため、cout ストリームに出力された文字列は表示されません。

#include <iostream>
#include <utility>

using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  string name;
  string nickname;

 public:
  MyClass1() = default;
  explicit MyClass1(string n) : name(std::move(n)) {
    cout << "Constructor 1 is called" << endl;
  };

  string getName() { return name; }

  string getNickname() { return nickname; }

  ~MyClass1() { cout << "Destructor is called" << endl; }
};

int main() {
  MyClass1 m1{};
  cout << m1.getName() << endl;
  cout << m1.getNickname() << endl;
  cout << "------------------" << endl;

  string n1("Maude");
  MyClass1 m2(n1);
  cout << m2.getName() << endl;
  cout << m2.getNickname() << endl;
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

出力:

------------------
Constructor 1 is called
Maude

------------------
Destructor is called
Destructor is called

C++ でオーバーロードを使用して複数のクラスコンストラクターを実装する

MyClass1 には、nickname と呼ばれる 2 番目の string データメンバーがあります。単一の string 値を取り、それを定義して nickname を初期化する別のコンストラクターを作成するとします。その場合、コンパイラーは、同じパラメーターで関数をオーバーロードできないというエラーを発生させます。したがって、別のコンストラクターを定義する必要があります。たとえば、2つの string 参照を受け取り、両方のデータメンバーを初期化するコンストラクターを選択しました。次のコードスニペットを実行すると、2 番目のコンストラクターが実行されたことがわかります。

コンストラクターにははるかに詳細な特性があり、この記事では主な機能のみを紹介しました。他の特別な関数には、move-constructor や copy-constructor のように、名前に-constructor という単語が含まれています。これら 2つは、まとめてコピー制御と呼ばれる特殊操作の一部です。デストラクタは、コンストラクタとは逆の動作をすることに注意してください。つまり、クラスメンバーの割り当てを解除し、通常、オブジェクトがスコープ外になると自動的に呼び出されます。与えられたコードスニペットを使用して、コンストラクタ-デストラクタ呼び出しの動作を簡単に観察できます。

#include <iostream>
#include <utility>
#include <vector>

using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  string name;
  string nickname;

 public:
  MyClass1() = default;
  explicit MyClass1(string n) : name(std::move(n)) {
    cout << "Constructor 1 is called" << endl;
  };

  // ERROR: Does not Compile
  //    MyClass1(string nk) : nickname(nk) {
  //        cout << "Constructor 3 is called" << endl;
  //    };
  MyClass1(string &n, string &nk) : name(n), nickname(nk) {
    cout << "Constructor 2 is called" << endl;
  };

  string getName() { return name; }

  string getNickname() { return nickname; }

  ~MyClass1() { cout << "Destructor is called" << endl; }
};

int main() {
  string n1("Maude");
  string n2("Bibi");

  MyClass1 m4(n1, n2);
  cout << m4.getName() << endl;
  cout << m4.getNickname() << endl;
  cout << "------------------" << endl;

  return EXIT_SUCCESS;
}

出力:

Constructor 2 is called
Maude
Bibi
------------------
Destructor is called
Destructor is called
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Class