繁体   English   中英

C ++ NULL指针和const正确性

[英]C++ NULL pointers and const correctness

我读到,删除指针数据成员后,在类的析构函数中进行检查是一种好习惯,如下所示:

if( 0 != m_pPointer)
{
    delete m_pPointer;
    m_pPointer= 0;
}

但是,我发现这阻止您将const指针声明为数据成员,如下所示:

Type* const m_pPointer;

为指针分配NULL (如上面的示例)不是const正确性的障碍吗? 最好的方法是什么? 保留所有const并停止为已删除的指针分配NULL或声明non-const指针,即使它们的地址永不改变?

这是不好的做法,原因如下:

  1. 在析构函数中将指针设置为null可能会掩盖双重破坏问题。 优良作法是尽早发现问题。
  2. delete指针之前检查指针是否为null只会添加不必要的代码。 delete通过不执行任何操作来处理空指针。 优良作法是尽量减少代码量。

确保删除空指针是安全的,因此空检查是毫无意义的。

如果一个类的成员是指向非const对象的const指针,那么您说的是指针值在包装对象的生存期内不会改变-既然如此,您应该仅在所指向的对象的生存时间将比包装对象长或更长,并且包装对象将永远都不想指向其他对象。

存在此问题的事实只是意味着您在错误的位置使用了const指针。 您声称在这种情况下指针值永远不会改变,但是在您的示例中,指针值显然会改变-更改为null。

当您将静态库与来自两个不同的共享库(在Linux上)的全局或静态对象链接在一起时,会导致一种奇怪的情况,这些共享库随后又链接到同一可执行文件。

每个共享的lib对象对构造函数和析构函数的insert调用,因此对于同一个对象,您将有一个对象,对构造函数和析构函数的两个调用(实际上,您将有2个对象映射到同一地址)。

当您的应用在第二个析构函数中崩溃时,您可能会发现问题。 如果您将其设置为NULL,则根本不会知道有任何问题。

您的问题:除上述问题外,我认为您应该区分两种类型的指针:请参见下面的类:

class A{
  obj *x, *y;
  A(){
    x = new obj;
    y = NULL
  }
  ~A(){
    delete x;
    if(y)delete y; // the `if` here will save the calling and returning run time when NULL. 
  }
  void RecicleX(){
    delete x;
    x = new obj;
  }
  void InitY(){
    assert(y==NULL); //illegal to call init when already
    y = new obj;
  }
  void TermY(){
    assert(y); //illegal to call term when already inited
    delete y;
    y = NULL; //prevent crush in dtor if called after...
  } 
};

x始终存在,因此无需检查它,也无需将其为null。 y可能存在但可能不存在,因此我认为删除后应将其为空。 (您可能还想知道当前状态,例如assert

“最佳方法”是:

class foo {
  std::unique_ptr<bar> m_pPointer;
public:
  foo(std::unique_ptr<bar> pPointer)
    : m_pPointer{std::move(pPointer)} {}
};

或const

class foo {
  const std::unique_ptr<bar> m_pPointer;
public:
  foo(std::unique_ptr<bar> pPointer)
   : m_pPointer{std::move(pPointer)} {}
};

没有new ,没有delete ,没有析构函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM