コピーコンストラクター

引数や戻り値を渡す際に、コンストラクターが呼ばれないというよりも、コピーコンストラクターが呼ばれる(のでデフォルトコンストラクターが呼ばれない)と考えたほうが良さそうだ。そして、コピーコンストラクターが未定義だと、暗黙的なコピーコンストラクターがあってそれが呼ばれている、と考えても良いのかも。

#include 
using namespace std;

class A {
public:
    A() {
        cout << "A::A()" << endl;
    }
    A(const A& a) {
        cout << "A::A(const A&)" << endl;
    }
    virtual ~A() {
        cout << "A::~A()" << endl;
    }
};

A foo() {
    cout << "b" << endl;
    A a;
    cout << "c" << endl;
    return a;
}

void main() {
    cout << "a" << endl;
    A a = foo();
    cout << "d" << endl;
}

だと、実行結果は、

a
b
A::A()
c
A::A(const A&)
A::~A()
d
A::~A()

となり、収支が合う。