Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6276969
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: C/C++

2013-08-20 11:02:38

原文地址:可怕的C++ 作者:dinglong08

一直以来很多人包括一些高手都说C++是恐怖的。首先C++的语法是庞杂的,我自己在学习有关模板部分,看了不知道多少遍了,但是一旦要到用的时候,还是得翻书,只能说没有理解,二者,C++兼顾过程程序设计模型和面向对象模型,这就是学他的人更加迷茫。这里还没有提及指针这个神奇的东西。

C++令人感到恐怖,从另一个角度可以略见一斑,即它在背后做了太多的事情。
下面的这个例子是在读 《C++沉思录》的时候发现的,作者讲的是代理的模式,而我在这里,要看看一些过程中C++背后作的事情。
代码如下:

点击(此处)折叠或打开

  1. #include <iostream>
  2. using namespace std;

  3. class A
  4. {
  5. public:
  6.     A() {
  7.         cerr << "A() been called" << endl;
  8.     }

  9.     virtual ~A() {
  10.         cerr << "~A() been called" << endl;
  11.     }

  12.     virtual A* copy() const = 0;
  13. };

  14. class B : public A
  15. {
  16. public:
  17.     B() {
  18.         cerr << "B() been called" << endl;
  19.     }

  20.     ~B() {
  21.         cerr << "~B() been called" << endl;
  22.     }

  23.     B(const B& b) {
  24.         cerr << "B(const B& b) been called" << endl;
  25.     }

  26.     A* copy() const {
  27.         cerr << "B::copy() been called" << endl;
  28.         return new B(*this);
  29.     }
  30. };

  31. class ProxyA
  32. {
  33. public:
  34.     ProxyA() {
  35.         cerr << "ProxyA() been called" << endl;
  36.         pa = 0;
  37.     }

  38.     ~ProxyA() {
  39.         cerr << "~ProxyA() been called" << endl;
  40.         delete pa;
  41.     }

  42.     ProxyA(const A& a) {
  43.         cerr << "ProxyA(const A& a) been called" << endl;
  44.         pa = a.copy();
  45.     }

  46.     ProxyA(const ProxyA& p) {
  47.         cerr << "ProxyA(const ProxyA& p) been called" << endl;
  48.         pa = (p.pa ? p.pa->copy() : 0);
  49.     }

  50.     ProxyA& operator=(const ProxyA& p) {
  51.         cerr << "ProxyA::operator = been called" << endl;
  52.         if (this != &p) {
  53.             delete pa;
  54.             pa = (p.pa ? p.pa->copy() : 0);
  55.         }
  56.         return *this;
  57.     }

  58. private:
  59.     A* pa;
  60. };

  61. int main(int argc, char* argv[])
  62. {
  63.     cerr << "----------- 0 ------------" << endl;
  64.     ProxyA ps[2];

  65.     cerr << "----------- 1 ------------" << endl;
  66.     B b;

  67.     cerr << "----------- 2 ------------" << endl;
  68.     ps[0] = b;

  69.     cerr << "----------- 3 ------------" << endl;
  70.     return 0;
  71. }
编译运行结果如下:

点击(此处)折叠或打开

  1. $ g++ a.cpp
  2. $ ./a.out
  3. ----------- 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有相似之处

这个例子的代码可以再进行深入的剖析,留给读者了,哈哈


阅读(399) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~