error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'

今天在一个类A中添加CArray m_PointArray;成员变量,竟然编译失败,提示如下信息

d:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afxtempl.h(262): error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'
5>          d:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afx.h(559) : see declaration of 'CObject::CObject'
5>          d:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afx.h(534) : see declaration of 'CObject'
5>          This diagnostic occurred in the compiler generated function 'CArray::CArray(const CArray &)'
5>          with
5>          [
5>              TYPE=POINT,
5>              ARG_TYPE=POINT
5>          ]

最开始很奇怪,这是很常见的定义,在我的另外一个类B中这样定义却没有问题。在网上查了圈,大概原因就是你的这个类A在外部有赋值构造函数被调用,即类似下面语句调用。
A a1;

A a2;

a2=a1;

或者你的类中有把CArray当作函数参数传递,编译会会产生CArray的赋值构造函数调用,即类似于a2.m_PointArray = a1.m_PointArray。

由于我的类A中没有自己定义赋值构造函数,所以编译器会生成默认赋值构造函数,编译器默认构造函数会调用a2.m_PointArray = a1.m_PointArray,但CArray的父类CObject中的赋值构造函数是私有的,导致编译失败。

我们的类中定义了CArray类型的成员,而CArray类的operator=是private类型(它继承自CObject::operator=,且被定义为private类型)。并给出了解决之道:如果我们的类/结构体中有CArray(或CList等其他的派生自CObject类)的成员变量,我们最好添加上一个public类型的operator=运算赋重载函数;

问题虽然是解决了,但是似乎还是没弄明白产生问题的根本原因:既然问题是由于CArray没有定义Operator=操作从而导致需要调用基类CObject中的私有Operator= 操作而引起的,那么为什么微软要将CObject的Operator=操作定义成私有呢?或者说为什么CObject在实际上并没有对Operator= 和拷贝构造函数做任何实质性的定义的情况下要去定义这两个函数,并且还将他们定义为private。。唯一的解释就是微软不希望继承自CObject的类 使用默认的Operator=操作,或者说微软不希望使用了CArray或者CList或者CMap的Collections模板类的类使用默认的Operator=操作。答案的确是如此,不仅如此,对于默认的拷贝构造函数结论也是一样(可能有些人碰到到同样的编译器报错,不过是针对拷贝构造函数的,后面我会解释引发这两种类型的报错的真正原因)。

要想搞清楚这个问 题,就先要了解C++编译器生成的默认函数——这些我们平时一直在使用却很少关心的幕后工作者到底是怎样工作的。当我们创建一个C++变量,为一个变量赋 值,或者调用一个C++函数,或者对一个C++变量进行取地址&操作时,这些都是一些基本操作,我们总是能得到我们想要的结果(至少看起来是这 样)因为这些都是C++的语义,而负责实现这些语义的是C++编译器。

编译器又是如何实 现这些语义的呢,比如当你构造一个C++变量时,编译器会检查你有没有为这个变量的类型创建一个构造函数,如果没有,编译器会自己帮你生成一个默认的构造 函数,从而实现了一个C++变量的构造;类似的,在用户执行其他一些诸如赋值操作,拷贝构造,取地址等基本操作时,编译器遵循同样的原则,即在用户未定义 相应的操作情况下自动生成一个默认的操作;正因为如此,甚至很多程序员并不知道它们的存在。

解决办法:

1.在头文件中定义  #define C2248_SWITCH    1

 

2.自定义赋值构造函数(其实我这的问题是没有自己定义拷贝构造函数,这是我们经常忽略的4个函数,https://blog.csdn.net/shejiannan/article/details/8911091)

 

参考链接:http://www.cppblog.com/hlong/archive/2007/11/20/37015.html

 

你可能感兴趣的:(VC学习)