CStringArray等一些MFC模板容器类不支持=操作的原因

来源:互联网 发布:求经典的网络军事小说 编辑:程序博客网 时间:2024/05/11 17:32

        最近,在做项目开发时,经常会使用链表。因为项目是基于MFC开发的,所以我选择MFC的一些模板类作为容器,而没有使用STL。

        当我想把一个类中的CStringArray利用“=”赋值给另一个CStringArray对象时,会产生编译错误,提示CStringArray对象不支持=操作。我不知道原因在哪,就从《C++ Primer》 中寻找答案,发现了两个重要的机制:

       第一,即使你没有为一个类定义赋值操作,它也会产生自己默认的赋值操作。也就是说,一个类默认是支持=操作的。而如果一个类定义了自己的赋值操作符函数,那么这个类就不会产生默认的赋值操作函数。

       第二,=操作未必会调用赋值操作函数(包括默认的),当=操作符的左操作数是一个未初始化的对象时就是这种情况。例如,

                                

上面代码这的=操作并没有调用赋值操作符函数,而是调用了“复制构造函数”。

        复制构造函数?这是什么东东,继续从《C++ Primer》中找答案。原来,复制构造函数是用类对象的引用来初始化另一个对象的。先让我们来看一下复制构造函数的形式:

                      

它像=操作符一样,如果一个类没有定义复制构造函数,那么这个类会自动产生一个默认的复制构造函数;而如果这个类定义了自己复制构造函数,那么它就不会产生默认的复制构造函数。

        现在,回到对正题的思考,既然一个类默认的是支持复制构造函数的,那为什么CStringArray还会不支持=操作呢?《C++ Primer》第13章讲复制控制时又说了,要想让一个类不支持复制初始化,也就是说,不能让类对象通过调用=来初始化另一个类对象,要类定义自己的复制构造函数,把它定义为private的。不过,private类型也可以通过声明友元来调用私有的复制构造函数。如果想断绝调用复制构造函数的一切可能性,就有一种办法:在类中声明复制构造函数,但不实现它。

        好,有了这些知识储备,我们再来看CStringArray的代码:

                   

       CStringArray是继承CObject的,再来看CObject的代码:

                           

      CObject把复制构造函数不仅定义为私有的,而且只声明没定义,所以当然就不支持=操作了(够绝吧)。

      再看CObject的代码,它不仅不支持复制构造函数,也不支持赋值操作符。所以,像CStringArray之类的派生于CObject的MFC模板容器类也不支持赋值操作符了。

      题目的问题已经解决,再说点题外话。复制构造函数是一个相对生僻点的概念,但它的使用频率却是非常高的。上文说的用=操作初始化对象是一种应用,还有在使用类对象作为参数传递时,也必须调用复制构造函数。不信,你可以调试一个以CStirng作为参数的函数,在执行这个函数时,你按F11一步一步执行,会看到执行到CString(CString &str)。如果参数类型不支持复制构造函数,那么只能使用类的引用或指针作为参数。

       还有一点一定要注意,我们常说的构造函数和复制构造函数是两码事,类定义了构造函数,但没有定义复制构造函数,仍然会生成默认的复制构造函数,两个互不相干。

原创粉丝点击