
[code]

    struct point {
        int x; int y;
        point(int a, int b) {
            x = a;
            y = b;
        }
    };
    class circle {
    public:
        point p;
        double r;
        circle(point a, double b) {
            p = a;
            r = b;
        }
        //circle(point a, double b) : p(a), r(b) {}; //no error
    };
    int main() {
        point p1(2,7);
        circle c(p1, 0.3);
        cout << c.p.x << c.p.y << endl;
        return 0;
    }
    
[/code]

質問： circle
のコンストラクタの部分で”クラスpointの規定のコンストラクタは存在しません”というエラーが出ます。pointの引数2個のコンストラクタを作成したはずなのになぜでしょうか。


CC BY-SA 3.0
2017-02-19T01:23:41.567
32780
2017-02-20T14:18:49.883
2017-02-19T03:13:32.580
19110
20713
question
c++
コンストラクタの設定


この形のコンストラクタ

[code]

    circle(point a, double b) {
        p = a;
        r = b;
    }
    
[/code]

は各親クラス及びフィールドの引数なしのコンストラクタ（＝デフォルトコンストラクタ）を呼び出すことになります。

クラスにコンストラクタが定義されていない場合、引数なしのコンストラクタは自動的に作成されます。`point`クラスには、ほかのコンストラクタ（`point(int,
int)`）が定義されていたから、引数なしのコンストラクタが自動的に作成されません。


CC BY-SA 3.0
2017-02-19T02:28:44.163
32782
2017-02-19T02:28:44.163
18621
32780
answer


コンストラクタでは`{...}`内の処理が始まる前にクラスメンバをすべて初期化します。  
この`circle`クラスのコンストラクタではメンバの初期化方法が記述されていない(`:`以降がない)  
ため、各メンバの「デフォルト」の初期化方法で初期化します。  
クラス、構造体のデフォルトの初期化方法は引数なしコンストラクタ呼び出しです。  
ですが、他の回答にあるように`circle`は引数2つのコンストラクタを定義しているので、  
引数なしのコンストラクタは暗黙には定義されません。

という理由で、ご質問のコンパイルエラーになっていると思います。  
エラーを回避するには以下のどちらかの方法をとるとよいと思います。

  1. 質問のコメントアウト箇所のように`p`を初期化する
  2. 構造体`point`に引数なしのコンストラクタを定義する

なお、もとのコードの「`p = a`」の箇所は代入演算子(`operator=()`)が実行されている  
はずです。暗黙に生成されるそれは「shallow copy」ですのでポインタが指している内容を  
コピーしたい場合、自前で「deep copy」する代入演算子を定義する必要があります。


CC BY-SA 3.0
2017-02-19T03:39:33.210
32786
2017-02-20T14:18:49.883
2017-02-20T14:18:49.883
20098
20098
32780
answer