Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止在C+中删除指针+; 有没有办法防止C++中的指针被声明删除?_C++ - Fatal编程技术网

防止在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:对象不一定会泄漏:对象可以
删除此
,或者通过其他方法(例如,public
release
方法等)公开
delete
功能。这样,您甚至无法在堆栈上创建foo。