[英]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
指针,即使它们的地址永不改变?
这是不好的做法,原因如下:
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.