#include <iostream>
class FooException
{
int id;
public:
FooException(int n) : id(n) {}
int getId() const { return id; }
};
class Foo;
class Bar
{
friend Foo;
int val;
Bar() : val(0) {}
Bar(const int v) : val(v) {}
Bar(const Bar& b) : val(b.val) {}
int getVal() const { return val; }
};
class Foo
{
Bar *p;
int id;
static int num() {
static int v = 0;
return v++;
}
public:
Foo() : id(num()), p(NULL) {
std::cout << "cons()" << id << std::endl;
p = new Bar;
}
Foo(const int val) : id(num()), p(NULL) {
std::cout << "cons(int)" << id << ":" << val << std::endl;
p = new Bar(val);
}
Foo(const Foo& f) : id(num()), p(NULL) {
std::cout << "cons(Foo)" << id << ":" << f.id << std::endl;
p = new Bar(*f.p);
}
~Foo() {
std::cout << "dest()" << id << std::endl;
delete p;
p = NULL;
}
Foo& operator = (const Foo& f) {
std::cout << id << " = " << f.id << std::endl;
p->val = f.p->val;
return *this;
}
int getValue() const {
if (p) return p->val;
throw FooException(id);
}
int getId() const {
return id;
}
};
Foo operator + (const Foo& f1, const Foo& f2) {
std::cout << f1.getId() << " + " << f2.getId() << std::endl;
Foo t(f1.getValue() + f2.getValue());
return t;
}
int main() {
using namespace std;
Foo f1, f2(123);
Foo f3(f2), f4, f5;
f4 = f3;
f5 = f2 + f3 + f2;
try {
cout << f1.getId() << " ... " << f1.getValue() << endl;
cout << f2.getId() << " ... " << f2.getValue() << endl;
cout << f3.getId() << " ... " << f3.getValue() << endl;
cout << f4.getId() << " ... " << f4.getValue() << endl;
cout << f5.getId() << " ... " << f5.getValue() << endl;
} catch (FooException e) {
cout << "fooerr" << e.getId() << endl;
} catch (...) {
cout << "err" << endl;
}
return 0;
}