Code Fix

中級

引数なしコンストラクタが無いときのエラーの原因

引数ありのコンストラクタだけを自分で定義したクラスに対して、引数なしでインスタンスを作ろうとしたときに出るエラーです。

エラーメッセージの読み方

main.cpp:8:11: error: no matching function for call to 'Timer::Timer()'
main.cpp
ファイル名
8
行番号
11
列番号 — この位置でg++が構文解析に失敗しました
no matching function for call to 'Timer::Timer()'
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  #include <iostream>
 2  class Timer {
 3  public:
 4      Timer(int seconds) { s = seconds; }
 5      int s;
 6  };
 7  int main() {
 8      Timer t   ;
                ^
 9      std::cout << t.s << std::endl;
10      return 0;
11  }
main.cpp:8:11: error: no matching function for call to 'Timer::Timer()'

Timer(int seconds)を自分で定義した時点で、引数なしのデフォルトコンストラクタは自動生成されなくなります。引数を渡して呼び出す必要があります。

直し方: (空) を (5) にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <iostream>
 2  class Rect {
 3  public:
 4      Rect(int w) { width = w; }
 5      int width;
 6  };
 7  int main() {
 8      Rect r    ;
                ^
 9      std::cout << r.width << std::endl;
10      return 0;
11  }
main.cpp:8:10: error: no matching function for call to 'Rect::Rect()'

「コンストラクタを書いても書かなくても引数なしで作れる」というのは誤解です。自分で1つでも定義すると暗黙のデフォルトコンストラクタは消えます。

直し方: (空) を (10) にします。

この問題を解いてみる →

パターン3

 1  #include <iostream>
 2  class Player {
 3  public:
 4      Player(int hp) { health = hp; }
 5      int health;
 6  };
 7  int main() {
 8      Player p     ;
                  ^
 9      std::cout << p.health << std::endl;
10      return 0;
11  }
main.cpp:8:12: error: no matching function for call to 'Player::Player()'

g++は候補一覧を出してくれますが、いずれも「0個の引数では呼べない」ことを伝えています。

直し方: (空) を (100) にします。

この問題を解いてみる →

パターン4

 1  #include <iostream>
 2  class Circle {
 3  public:
 4      Circle(int r) { radius = r; }
 5      int radius;
 6  };
 7  int main() {
 8      Circle c   ;
                 ^
 9      std::cout << c.radius << std::endl;
10      return 0;
11  }
main.cpp:8:12: error: no matching function for call to 'Circle::Circle()'

Circle(int r)を自分で定義した時点で、引数なしのデフォルトコンストラクタは自動生成されなくなります。

直し方: (空) を (3) にします。

この問題を解いてみる →

パターン5

 1  #include <iostream>
 2  class Bank {
 3  public:
 4      Bank(int b) { balance = b; }
 5      int balance;
 6  };
 7  int main() {
 8      Bank b     ;
                ^
 9      std::cout << b.balance << std::endl;
10      return 0;
11  }
main.cpp:8:10: error: no matching function for call to 'Bank::Bank()'

引数を1つでも取るコンストラクタを定義すると、暗黙のデフォルトコンストラクタは消えます。

直し方: (空) を (500) にします。

この問題を解いてみる →

よくある誤解

「コンストラクタを1つも書かなくても、書いても、引数なしで常に作れる」というのは誤解です。コンパイラが自動で用意してくれる引数なしのデフォルトコンストラクタは、自分でコンストラクタを1つでも定義した時点で生成されなくなります。

実務での勘所

他のコンストラクタを書きつつ、引数なしの既定のコンストラクタも残したい場合、C++11以降はMyClass() = default;と明示的に書くことができます。これは「コンパイラが自動生成するはずだった実装をそのまま使う」という意味の宣言で、自分でロジックを書かずに済みながら、他のコンストラクタを定義したことで失われた既定のコンストラクタを明示的に復活させられます。空の中身{}を自分で書くのと結果はほぼ同じですが、= defaultのほうが意図が明確に伝わります。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)