ページ 11

C++のコンストラクタ

Posted: 2012年12月23日(日) 22:56
by みけCAT
IdeoneでC++の実験をしていて、気になったことがあるので質問します。

コード:

#include <cstdio>

class test {
    public:
        test();
        test(int a);
        test(int a,int b);
};

test::test() {
    puts("test()");
}

test::test(int a) {
    puts("test(int a)");
}

test::test(int a,int b) {
    puts("test(int a,int b)");
}

int main(void) {
    test a();
    test b(123);
    test c(123,456);
    return 0;
}
このコードを実行すると、

コード:

test(int a)
test(int a,int b)
と出力されました。
すなわち、引数が0個のコンストラクタは呼ばれていないということです。

また、

コード:

#include <cstdio>

class test {
    public:
        test();
        test(int a);
        test(int a,int b);
};

test::test() {
    puts("test()");
}

test::test(int a) {
    puts("test(int a)");
}

test::test(int a,int b) {
    puts("test(int a,int b)");
}

int main(void) {
    test a=test();
    test b=test(123);
    test c=test(123,456);
    return 0;
}
このコードを実行すると、

コード:

test()
test(int a)
test(int a,int b)
と表示され、きちんと引数が0個のコンストラクタも呼ばれていることがわかります。

なぜ最初の書き方では、引数が0個のコンストラクタは呼ばれないのでしょうか?

[hr]
という質問文を書きながらさらに実験をしたところ、つぎのことがわかりました。

コード:

#include <cstdio>

class test {
    public:
        test();
        test(int a);
        test(int a,int b);
        void mikisin();
};

test::test() {
    puts("test()");
}

test::test(int a) {
    puts("test(int a)");
}

test::test(int a,int b) {
    puts("test(int a,int b)");
}

void test::mikisin() {
    puts("Hizikata mikisin");
}

int main(void) {
    test a();
    test b(123);
    test c(123,456);
    a.mikisin();
    return 0;
}
このコードを実行しようとしたところ、

コード:

prog.cpp: In function ‘int main()’:
prog.cpp:31: error: request for member ‘mikisin’ in ‘a’, which is of non-class type ‘test ()()’
というエラーが出ました。
すなわち、

コード:

test a();
は何らかの別の型として認識されていると考えられます。
もしかして、これは関数ポインタになっているということでしょうか?
‘test ()()’とは何でしょうか?

Re: C++のコンストラクタ

Posted: 2012年12月23日(日) 23:13
by h2so5

コード:

test a();
はtest型の値を返し引数を取らない関数aのプロトタイプ宣言として解釈されるようです。

Re: C++のコンストラクタ

Posted: 2012年12月24日(月) 09:55
by みけCAT
なるほど。ありがとうございます。
引き続き「‘test ()()’とは何でしょうか?」

Re: C++のコンストラクタ

Posted: 2012年12月24日(月) 10:44
by beatle
aが関数名だと解釈されたため、a.mikisin()が無効なので変なエラーになっています。
aは関数名、つまり式の中でのaの型が
test ()()
です。

ちなみに、Aを返し、Bを引数に取る関数へのポインタpは次のように宣言します。

コード:

A (*p)(B);

Re: C++のコンストラクタ

Posted: 2012年12月24日(月) 11:16
by とっち
私も興味をもったのでいろいろ実験したところ、
以下のコードは実行できました。

コード:

#include <iostream>
using namespace std;

class CTest{
public:
    void print(){cout<<"start"<<endl;}
};

int main(void){
    CTest a();
    a().print();
    cout<<"end"<<endl;
}

CTest a(){
    CTest t;
    cout<<"a"<<endl;
    return t;
}
実行結果は
a
start
end

となりました。

Re: C++のコンストラクタ

Posted: 2012年12月24日(月) 12:07
by みけCAT
なるほど。
ありがとうございました。