1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

包含したクラスのコンストラクタに引数を渡す

Last updated at Posted at 2019-05-26

C++勉強中のメモ。あとqiitaに記事を上げる練習

結論

クラスにクラスを包含するときに、包含したクラスのコンストラクタに引数を渡したい場合は、初期化の際にコンストラクタを呼ぶ。

クラスのメンバ変数にクラスを持たせる

クラスのメンバ変数としてクラスを持たせた場合、なにもしなくてもデフォルトコンストラクタが呼ばれる。

test1.cpp
#include <iostream>
class Test1{
    public:
        Test1();
};

class Test{
    public:
        Test();
    private:
        Test1 test1;
};

Test1::Test1(){
    std::cout << "Constructor:Test1" << std::endl;
}

Test::Test(){
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}
実行結果
Constructor:Test1
Constructor:Test

また、コンストラクタは包含したクラスから呼ばれていることもわかる。

引数を持つクラスを包含する

先程のTest1クラスのコンストラクタに引数を設定してみる。
とりあえずなにも考えずこう書くとコンパイルはエラーを吐かなくなった。

test2.cpp
#include <iostream>
class Test1{
    public:
        Test1(int a);
};

class Test{
    public:
        Test();
    private:
        Test1 test1(int a);
};

Test1::Test1(){
    std::cout << "Constructor:Test1" << std::endl;
}

Test::Test(){
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}

が、実行してみるとこうなる。Test1のコンストラクタが呼ばれていない。

実行結果
Constructor:Test

冷静に考えると引数に渡しているaには実体がないので、これでTest1のコンストラクタが呼ばれても困る。
(コンパイラに怒って欲しかった。)

追記

コンパイルが通るのも当然で、ここで宣言しているのはコンストラクタではなくただのメンバ関数だった。
ちなみにこのように書くと、Test1クラスにはデフォルトコンストラクタがないぞとIDEも怒ってくれるしコンパイルは通らない。

test2.cpp
#include <iostream>
class Test1{
    public:
        Test1(int a);
};

class Test{
    public:
        Test();
    private:
        Test1 test1;
};

Test1::Test1(){
    std::cout << "Constructor:Test1" << std::endl;
}

Test::Test(){
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}

コンストラクタでクラスを初期化する

メンバとしてクラスなどのオブジェクトを持たせた場合でも、普通の変数と同様にコンストラクタで初期化ができる。

test3.cpp
#include <iostream>
class Test1{
    public:
        Test1(int a);
};

class Test{
    public:
        Test();
    private:
        Test1 test1;
};

Test1::Test1(int a){
    std::cout << "Constructor:Test1" << " argument:" << a << std::endl;
}

Test::Test():
    test1(1)//初期化でコンストラクタを呼ぶ
{
    std::cout << "Constructor:Test" << std::endl;
}

int main(){
    Test test;
    return 0;
}
実行結果
Constructor:Test1 argument:1
Constructor:Test

コンストラクタが呼ばれた。引数を渡すこともできている。

1
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?