c++类中的包含机制


 本人在学习Qt的时候发现了一个非常有趣的现象。有很多函数的调用方法都写成了如下的形式:

object.func().func2();

这令小弟着实不懂。在上面这段代码中,第一个对象调用它的成员函数func()是完全没有问题的,但是后面那个func2()就奇怪了。我们只知道,点运算符(.)的作用就是调用对象的成员,但是如果按照上面这个程序的字面意思来理解,就是对象object调用它的成员函数func(),然后函数func()再调用它的成员函数func2()。这怎么能解释得通哩??我们只知道对象有成员函数,但是从来没有听说过函数也可以有成员函数的啊。没有办法,只有翻C++的工具书,最后,居然发现了这个原来就是C++中的“包含”思想。那么究竟何为包含呢,且听小弟慢慢叙来......^_^

      何为“包含”,其实说白了就是一个类可以包含另一个类的对象。即如下程序所示:

class A
{
                   //...
 
};
 
class B
{
                   //...
    A a;
    A b;
};

在上面这个程序中,我们定义了类A和类B。其中类B里面我们定义了类A的两个对象a和b。这样的情况就叫类B包含了类A。

下面,我们用一个程序来看一下“包含”:

 1 //#include <stdio.h>
 2 //#include <stdlib.h>
 3 #include <iostream>
 4 using namespace std;
 5 
 6 class A
 7 {
 8 public:
 9     A(int i) :x(i)
10     {
11         cout << "A's constructor" << endl;
12     }
13 
14     void getx()
15     {
16         cout << "A's a is" << x << endl;
17     }
18     ~A()
19     {
20         cout << "A's destructor" << endl;
21     }
22 
23 private:
24     int x;
25 
26 };
27 
28 class B
29 {
30 public:
31     B(int x,int z) :a(x), z(z)
32     {
33         cout << "B' constructor" << endl;
34     }
35 
36     A& getA()
37     {
38         return a;
39     }
40     
41     ~B()
42     {
43         cout << "B's destructor" << endl;
44     }
45 
46 private:
47     A a;
48     int z;
49 
50 
51 };
52 
53 void playstage()
54 {
55     B b1(1,2);
56     b1.getA().getx();
57 }
58 
59 void main()
60 {
61     playstage();
62     system("pause");
63     
64     
65 }
  • 首先对两个类进行分析:在上面这个程序中,我们定义了两个类A和B。其中可以看到,在类B的私有成员变量里面,我们定义了一个类B自己的成员变量,另外还定义了类A的对象a(47行);另外在类B的公有函数中,我们定义了返回值为类A的函数:getA(),它的作用就是返回在类B中定义的类A的对象a。在这里我们特别应该注意的是类B的构造函数:
B(int x,int z) :a(x), z(z)

这个构造函数很有意思。我们可以看到它不仅初始化了自己的私有成员变量z,而且也顺带初始化了类A的对象a。那么它肯定会调用类A的构造函数。然后再调用B类自己的构造函数。那么析构的时候顺序应该就是相反的,首先调用B类的析构函数,然后再调用A类的析构函数。我们可以看到后面的程序输出图这样说滴,^_^。(见输出的红色框)

此处怎么比我们预计的多了一项输出呢?(箭头所指处)。。

因为在调用b1.getA().getX()时,getA()返回了我们所创建的A类的对象a,此处相当于复制了一份(其实是调用了默认的copy构造函数)。所以我们最后需要多析构一次对象a.(作为返回值调用copy构造函数)

下面来印证我的猜想:

我们在类A中定义copy构造函数,其他代码不变。

 1 class A
 2 {
 3 public:
 4     A(int i) :x(i)
 5     {
 6         cout << "A's constructor" << endl;
 7     }
 8     A(A &a)
 9     {
10         x = a.x;
11         cout << "A's copy constructor" << endl;
12     }
13     void getx()
14     {
15         cout << "A's a is" << x << endl;
16     }
17     ~A()
18     {
19         cout << "A's destructor" << endl;
20     }

输出如下:

 

看到了吧!!    (0.0)

其实,我们为了避免拷贝构造函数的使用,我们可以返回A类的引用。这样就避免了copy构造函数的调用。

    //A getA()
    A& getA()
    {
        return a;
    }

输出如下:

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM