一直以来很多人包括一些高手都说C++是恐怖的。首先C++的语法是庞杂的,我自己在学习有关模板部分,看了不知道多少遍了,但是一旦要到用的时候,还是得翻书,只能说没有理解,二者,C++兼顾过程程序设计模型和面向对象模型,这就是学他的人更加迷茫。这里还没有提及指针这个神奇的东西。
C++令人感到恐怖,从另一个角度可以略见一斑,即它在背后做了太多的事情。
下面的这个例子是在读 《C++沉思录》的时候发现的,作者讲的是代理的模式,而我在这里,要看看一些过程中C++背后作的事情。
代码如下:
-
#include <iostream>
-
using namespace std;
-
-
class A
-
{
-
public:
-
A() {
-
cerr << "A() been called" << endl;
-
}
-
-
virtual ~A() {
-
cerr << "~A() been called" << endl;
-
}
-
-
virtual A* copy() const = 0;
-
};
-
-
class B : public A
-
{
-
public:
-
B() {
-
cerr << "B() been called" << endl;
-
}
-
-
~B() {
-
cerr << "~B() been called" << endl;
-
}
-
-
B(const B& b) {
-
cerr << "B(const B& b) been called" << endl;
-
}
-
-
A* copy() const {
-
cerr << "B::copy() been called" << endl;
-
return new B(*this);
-
}
-
};
-
-
class ProxyA
-
{
-
public:
-
ProxyA() {
-
cerr << "ProxyA() been called" << endl;
-
pa = 0;
-
}
-
-
~ProxyA() {
-
cerr << "~ProxyA() been called" << endl;
-
delete pa;
-
}
-
-
ProxyA(const A& a) {
-
cerr << "ProxyA(const A& a) been called" << endl;
-
pa = a.copy();
-
}
-
-
ProxyA(const ProxyA& p) {
-
cerr << "ProxyA(const ProxyA& p) been called" << endl;
-
pa = (p.pa ? p.pa->copy() : 0);
-
}
-
-
ProxyA& operator=(const ProxyA& p) {
-
cerr << "ProxyA::operator = been called" << endl;
-
if (this != &p) {
-
delete pa;
-
pa = (p.pa ? p.pa->copy() : 0);
-
}
-
return *this;
-
}
-
-
private:
-
A* pa;
-
};
-
-
int main(int argc, char* argv[])
-
{
-
cerr << "----------- 0 ------------" << endl;
-
ProxyA ps[2];
-
-
cerr << "----------- 1 ------------" << endl;
-
B b;
-
-
cerr << "----------- 2 ------------" << endl;
-
ps[0] = b;
-
-
cerr << "----------- 3 ------------" << endl;
-
return 0;
-
}
编译运行结果如下:
-
$ g++ a.cpp
-
$ ./a.out
-
----------- 0 ------------
ProxyA() been called
ProxyA() been called
----------- 1 ------------
A() been called
B() been called
----------- 2 ------------
ProxyA(const A& a) been called
B::copy() been called
A() been called
B(const B& b) been called
ProxyA::operator = been called
B::copy() been called
A() been called
B(const B& b) been called
~ProxyA() been called
~B() been called
~A() been called
----------- 3 ------------
~B() been called
~A() been called
~ProxyA() been called
~ProxyA() been called
~B() been called
~A() been called
解说如下:
1. ProxyA 有默认的构造函数,这样就可以定义ProxyA的数组
2. 在 “--- 1 ---” 和 “--- 2 ----” 先调用基类的构造函数再调用自己的构造函数,这个不用太多的说明
3. 主要个是接下来 “--- 2 ---” 到 “--- 3 ---” 之间的部分
将一个 B 的对象,赋值给一个 ProxyA 的对象,那么C++先试着用 B 的对象构造 ProxyA 的对象,这样在 ProxyA 中找到了合适的构造函数 ProxyA
(const A
& a
)
因为copy是序函数,这样B的copy被调用 B
::copy
(),该调用中构造了B对对象,所以 A 和 B的构造函数调用 A
(),B
(const B
& b
)
到目前为止,使用 B 的对象构造出了 ProxyA 对象
接下来发现 ProxyA 重载了 = 运算符,故调用之,ProxyA
::operator
=
在重载的运算符调用中,有delete pa
紧接着调用 B 的 copy
接着刚才临时构造的 ProxyA 对象被稀构
4. 接下来的修改函数不用多说了
这里可以看到一个赋值带来了多少对象的构造,二者些都是背后进行的
注意这里的proxy模式也值得体会
这里的copy方式和java的clone有相似之处
这个例子的代码可以再进行深入的剖析,留给读者了,哈哈
阅读(3064) | 评论(0) | 转发(1) |