0

这是我的班级设置的精简版:

class CMyClass : public CDialog
{
    CMyClass(CWnd *pParent = NULL); // constructor
    ~CMyClass();
    _ CBrush *_pRadBkgColor; // background color of a radio button
}

CMyClass::CMyClass(CWnd *pParent /*=NULL*/)
{
    // assign CBrush pointer to a new brush
    _pRadBkgColor = new CBrush(RGB(0xFF, 0xFF, 0xFF));
}

CMyClass::~CMyClass()
{
    if( _pRadBkgColor != NULL )
    {
        delete _pRadBkgColor
    }
    _pRadBkgColor = NULL;
}

现在,当我运行一个分析代码以查找细微错误的工具时,我得到了这个:

没有赋值运算符的类“名称”的构造函数中的新函数——在被引用类的构造函数中,出现了一个新函数。但是,没有为此类声明赋值运算符。大概一些类成员(或成员)指向动态分配的内存。默认赋值运算符未正确处理此类内存。通常需要自定义赋值运算符。因此,如果 x 和 y 都是 Symbol x = y 类型;将导致指针重复。稍后删除会造成混乱。

我相信它告诉我,如果我有两个成员变量是 CBrush 指针,让我们调用它们a和最好保持不变),然后我删除or ,就会有混乱。banewb = aaab

如果我不做这样的任务,这安全吗?

谢谢史蒂文

4

3 回答 3

1

警告说,如果制作了副本,CMyClass那么两者的两个实例CMyClass都指向同一个CBrush. 如果其中一个CMyClass实例被破坏,则另一个实例留下一个指向 a 的悬空指针,CBrush因为被破坏的实例将其CMyClass删除。

如果您有一个动态分配的成员,那么您需要实现一个复制构造函数和赋值运算符以正确复制动态分配的成员或通过声明复制构造函数和赋值运算符使类不可复制private

class CMyClass : public CDialog
{
public:
    CMyClass(CWnd *pParent = NULL);
    ~CMyClass();
private:
    CBrush *_pRadBkgColor;
    CMyClass(const CMyClass&);             // Copy constructor.
    CMyClass& operator=(const CMyClass&);  // Assignment operator.
};

请参阅什么是三法则?.

于 2012-05-03T22:08:29.840 回答
0

析构函数中的检查_pRadBkgColor != NULL是不必要的。delete可以用NULL指针调用。以下内容就足够了:

CMyClass::~CMyClass() 
{
    delete _pRadBkgColor 
    _pRadBkgColor = NULL; 
} 
于 2012-05-03T22:13:00.137 回答
0

您的代码没有任何问题。如果一个对象是用new分配的,那么它必须通过调用delete显式释放。您的代码正是这样做的。

此外,还有一个称为RAII的成语进一步描述了为什么您所做的事情是正确的。

但是,堆栈分配的变量通常更快,您可以使用以下代码回避整个问题:

class CMyClass : public CDialog
{ 
  CMyClass(CWnd *pParent = NULL);
  ~CMyClass();
 _ CBrush _pRadBkgColor;
}

CMyClass::CMyClass(CWnd *pParent /*=NULL*/)
      : _pRadBkgColor(RGB(0xFF, 0xFF, 0xFF))
{
  HBRUSH hBr = _pRadBkgColor; // no problem, conversion operator.
}

CMyClass::~CMyClass()
{

}
于 2012-05-03T22:43:02.380 回答