防止在C+中删除指针+; 有没有办法防止C++中的指针被声明删除?
我尝试了以下代码,但运气不好防止在C+中删除指针+; 有没有办法防止C++中的指针被声明删除?,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 w
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
增编:
但是我也遇到过类似的情况。。我的解决方案是停止使用普通指针,因此不必担心删除。在我的例子中,共享指针是有意义的,但是一个唯一的指针或类似的指针就足够了
//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
}
//自定义不执行任何操作的删除程序。
模板不删除(T*){/*什么都不做*/}
共享\u ptr const foo()
{
静态int a;
返回共享\u ptr(&a,&T\u delete);
}
共享\u ptr常量条()
{
返回共享_ptr(新int(7));
}
main()
{
共享_ptr p1=foo();
共享_ptr p2=bar();
//p1s数据未在此处删除,
//p2s数据在此删除
}
您不能以阻止对指针调用delete
的方式声明指向任意类型的指针。这就是为什么
如果是指向自定义类的指针,则可以将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!
}
我不完全明白你在问什么。如果您想要一个无法删除的对象,可以尝试将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”设为公共变量,因为它最初定义为结构,但您可以(也应该)将其设为私有变量,并使访问器强制执行您在原始代码示例中想要的访问规则
这不是万无一失的,编译器只会捕获对该类的直接引用。我认为他的意思是意外删除对象(无论是delete o还是free(o)),这可能会导致程序崩溃。在堆上分配对象真的没有办法解决这个问题;就堆栈指针而言,我们都知道这是不可能发生的。 在顶级类中使用受保护的dtor是一个选项,但是您必须在子类dtor中调用它 一种解决方案(即使覆盖delete操作符在表上)是使用一个表映射系统,该系统返回一个id/token/what have you,但这实际上只适用于使用CSTYLE编写代码和使用C约定编译的情况。这样做的好处是对用户隐藏对象指针,允许用户传入映射到对象的令牌。这需要工作和经验
我甚至不担心它,因为大多数有经验和智慧的程序员都会阅读API的文档来避免这种灾难。如果你有智慧或经验,那么,我不知道该说什么。你可以阻止在某些类的指针上使用delete操作符。 例如:
类对象{
公共:作废运算符删除(作废*p)=删除;
};
类实体:公共对象{};
int main(int argc,char const*argv[]
{
对象*o=新对象;
实体*e=新实体;
删除o;//编译器错误
删除e;//编译器错误
返回0;
}
由于删除了Object::operator delete,因此无法删除从Object继承的所有类。不要将此运算符标记为private,因为它在派生或实例化对象类时会导致编译器错误。请注意,我们仍然可以这样做:
::操作员删除(o);
这将释放o指针,但不会调用析构函数。
使用类来管理对象类的生命周期。一个简单的实施方案是:
类对象{
模板好友类ptr;
公共:作废运算符删除(作废*p)=删除;
};
类实体:公共对象{};
模板
类Ptr{
公众:
Ptr(type*obj):o(obj){}
~Ptr(){o->~type();::运算符delete(o);}
私人:o型;
};
int main(int argc,char const*argv[]
{
对象*o=新对象;
实体*e=新实体;
//删除o;//错误
//删除e;//错误
Ptr ent=新实体;//Ptr将为您删除ent。
返回0;
}
好问题,+1,但我很确定,这是不可能的(除非你使用一些包装器/智能指针)@Felics你最终会如何释放内存呢?@PaulManta我不想释放内存,这是重点。指针指向一个静态变量。@PaulManta我不想“解决问题”,我只想知道这是否可行。不。返回引用将是一个很好的信号,表明您不希望删除对象。受保护的删除在某些情况下也更有意义。我的想法也是:我们使用类来封装数据(并定义有效的操作)。在实际释放内存之前重写delete global并执行一些检查如何?是否也应该将运算符设为新的私有/受保护-这样就不会泄漏堆上的值?@MichaelAnderson:对象不一定会泄漏:对象可以删除此
,或者通过其他方法(例如,publicrelease
方法等)公开delete
功能。这样,您甚至无法在堆栈上创建foo。