防止在C++中的指针上删除
Prevent delete on pointer in C++
有没有办法防止通过声明删除C++中的指针?
我尝试过遵循代码,但没有运气。
const int* const foo()
{
static int a;
return &a;
}
int main()
{
const int* const a = foo();
*a = 1; //compiler error, const int*
a++; //compiler error, int* const
delete a; //no compiler error, I want to have compiler error here
return 0;
}
以防止在指针上调用delete
的方式声明指向任意类型的指针。删除指向 const (T const*) 的指针解释了为什么会这样。
如果它是指向自定义类的指针,则可以将delete
运算符设为私有:
class C {
void operator delete( void * ) {}
};
int main() {
C *c;
delete c; // Compile error here - C::operator delete is private!
}
您当然不应该将析构函数设为私有(如其他人建议的那样),因为它也会避免在堆栈上创建对象:
class C {
~C() {}
};
int main() {
C c; // Compile error here - C::~C is private!
}
简单的答案是否定的。无法防止在指向内置类型的指针上调用 delete。
增发:
但是,我遇到了与此类似的情况..我的解决方法是停止使用普通指针,因此无需担心删除。就我而言,共享指针是有意义的,但是唯一的指针或类似指针可能就足够了。
//Custom do nothing deleter.
template<typename T> dont_delete( T* ) { /* Do Nothing */ }
shared_ptr<const int> const foo()
{
static int a;
return shared_ptr<const int>(&a, &dont_delete<const int> );
}
shared_ptr<const int> const bar()
{
return shared_ptr<const int>(new int(7) );
}
main()
{
shared_ptr<const int> p1 = foo();
shared_ptr<const int> p2 = bar();
//p1s data _not_ deleted here,
//p2s data is deleted here
}
我不完全明白你在问什么。如果你想要一个无法删除的对象,你可以尝试将foo作为一个类,并使析构函数私有。
class Foo {
public:
int a;
Foo(int v) {
a = b;
}
private:
~Foo() { }
};
int main() {
Foo *c = new Foo(1);
delete c; // compiler error, ~Foo() is private
return 0;
}
我公开了变量"a",因为它最初被定义为结构,但您可以(并且应该)将其设为私有,并使访问器强制执行您在原始代码示例中所需的访问规则。
这不是万无一失的,编译器只会捕获对该类的直接引用。
我认为他的意思是意外删除对象(无论是删除o还是free(o)),这可能导致程序崩溃。在堆上分配对象确实没有办法解决这个问题;就堆栈指针而言,我们都知道这不可能发生。在顶级类中使用受保护的 dtor 是一个选项,但您必须在子类 dtor 中调用它。
一种解决方案(即使覆盖删除运算符在表上)是使用返回 id/token/what-have-you 的表映射系统,但这实际上仅适用于您用 CSTYLE 代码编写和用 C 约定编译。这样做的好处是隐藏了来自用户的对象指针,允许用户传入映射到对象的令牌。这需要工作和经验才能完成。
我什至不会担心它,因为大多数经验和明智的程序员都会阅读 API 的文档以避免这种事故。如果下界明智或经验,好吧,那我就不该说了。
您可以阻止在某些类的指针上使用删除运算符。例如:
class Object {
public: void operator delete(void* p) = delete;
};
class Entity : public Object { };
int main(int argc, char const *argv[])
{
Object* o = new Object;
Entity* e = new Entity;
delete o; // compiler error
delete e; // compiler error
return 0;
}
对于从 Object 继承的所有类,无法删除,因为删除了 Object::运算符。不要将此运算符标记为私有,因为它会在派生或实例化 Object 类时给出编译器错误。请注意,我们仍然可以这样做:
::operator delete(o);
这将释放 o 指针,但不会调用析构函数。使用类来管理对象类的生存期。一个简单的实现是:
class Object {
template<typename type> friend class ptr;
public: void operator delete(void* p) = delete;
};
class Entity : public Object { };
template<typename type>
class Ptr {
public:
Ptr(type* obj) : o(obj){}
~Ptr() { o->~type(); ::operator delete(o); }
private: type* o;
};
int main(int argc, char const *argv[])
{
Object* o = new Object;
Entity* e = new Entity;
// delete o; // error
// delete e; // error
Ptr<Entity> ent = new Entity; // Ptr will delete ent for you.
return 0;
}
- 使用函数引用指向节点的指针删除链表中的节点?
- 如何通过指向元组的共享指针删除对象
- 函数内的 C++ 指针删除
- 一个对象的两个指针.删除了一个指针,对象仍然存在
- 如何通过存储在 std::list 中的指针删除对象?
- C++中的智能指针删除
- 将C 中的每个指针删除作为阵列的指针安全吗?
- 使用 C 字符串和指针.删除除小写和空格以外的任何字符
- 在特定情况下,指针删除和铸造之间的关系不清楚
- 提升属性树:使用指向节点及其父节点的指针删除节点
- 警告C4150在尝试包装本机C 类时,指向不完整类型的指针删除
- C++ Valgrind 双指针删除,用于防止内存泄漏
- C 通过指向其基类的指针删除派生对象
- 将指针删除到数组
- 当通过其中一个指针删除对象时,C++将所有指针设置为null
- 智能指针删除器和"using"名称为"pointer"关键字
- 通过指向其基的指针删除 POD 对象是否安全
- 模板化的出列无效指针:删除类时失败
- 使用"this"指针删除
- (C++) list.error 方法和使用指针删除内存