可以将成员变量 (CBrush *) 分配给在类构造函数中动态分配的内存,并出现新的原因问题

Can assigning a member variable (CBrush *) to memory dynamically allocated in a class constructor with new cause problems?

本文关键字:内存 动态分配 问题 构造函数 变量 成员 CBrush 分配      更新时间:2023-10-16

这是我的类设置的精简版本:

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;
}

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

在没有

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

我相信它告诉我,如果我有两个成员变量是 CBrush 指针,让我们称它们为 ab ,并且我在构造函数中使用 new 初始化a,然后稍后我说b = a(或将a分配给任何其他地址真的......我想最好让它保持不变(,然后我删除ab,会有混乱。

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

谢谢史蒂文

警告说,如果制作了CMyClass的副本,那么CMyClass的两个实例都指向同一个CBrush。如果其中一个CMyClass实例被销毁,则另一个实例将留下一个悬空指针,指向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.
};

请参阅什么是三法则?。

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

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

你的代码没有错。如果一个对象分配了 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()
{
}