#include <iostream>
using namespace std;
class B;
int getdatafromb(const B& b);
class A {
friend class B;
int data;
public:
// explicit を付けると引数渡しと戻り値におけるコピーコンストラクタが働かずエラー
A(const A& a) : data(a.data) { cout << "A::A(const A&)" << endl; }
//
explicit A(int i) : data(i) { cout << "A::A(int)" << endl; }
// -pedantic では 以下の explicit を削るとエラー
explicit A(const B& b) : data(getdatafromb(b)) { cout << "A::A(const B&)" << endl; }
A& operator=(const A& a) {
this->data = a.data;
cout << "A::operator=(const A&)" << endl;
return *this;
}
A& operator=(const int& i) {
this->data = i;
cout << "A::operator=(const int&)" << endl;
return *this;
}
A& operator=(const B& b) {
this->data = getdatafromb(b);
cout << "A::operator=(const B&)" << endl;
return *this;
}
~A() { cout << "A::~A()" << endl; }
};
class B {
friend int getdatafromb(const B& b);
int data;
public:
B() : data(0) {
cout << "B::B()" << endl;
}
operator A() const {
cout << "B::operator A()" << endl;
return A(data);
}
};
inline int getdatafromb(const B& b) {
return b.data;
}
int main(int argc, char** argv) {
cout << "a" << endl;
A a(1); // A::A(int)
cout << "b" << endl;
A b = a; // A::A(const A&) .. copy-initialization
cout << "c" << endl;
A c(a); // A::A(const A&) .. direct-initialization
cout << "d" << endl;
A d = A(20); // A::A(int) のみ direct-initialization, then copy-initialization (最適化でcopy-は消える)
cout << "assignment a=b" << endl;
a = b; // A::operator=(const A&)
// cout << "e" << endl;
// A e = 1;
// ^ error; A::A(int) に explicitが付いているため.
// また intからA&への暗黙の変換はない (intクラスを作ってoperator A()を追加することはできない)
cout << "f" << endl;
B f; // B::B()
cout << "g" << endl;
A g(f); // A::A(const B&) .. direct-initialization
cout << "h" << endl;
A h = f; // B::operator A(), then copy-initialization (最適化でcopy-は消える)
}