公共的operator new,私有的operator delete:使用new时出现C2248“无法访问私有成员”的错误。

19

一个类重载了运算符newdelete。其中new为公共的,delete为私有的。

当我构造这个类的实例时,我得到了下面的错误:

pFoo = new Foo(bar)

example.cpp(1): error C2248: 'Foo::operator delete': cannot access private member declared in class 'Foo'

这里没有调用 delete,那么编译器到底在想什么呢? :)

  1. 出现错误的原因是什么?
  2. 可否不使用成员函数 CreateInstance 解决此问题?
5个回答

28
当执行new Foo()时会发生两件事情:首先调用operator new来分配内存,然后调用Foo的构造函数。如果构造函数抛出异常,由于无法访问已经分配的内存,C++运行时将通过将其传递给适当的operator delete来处理它。这就是为什么您总是必须为您编写的每个operator new实现匹配的operator delete,并且它需要可访问性的原因。
作为一种解决方法,您可以将它们都设置为私有,并从公共成员函数(如create())调用operator new

3

请查看这个链接。在其中一个较低的段落中提到,new需要访问delete。简单来说,如果您可以删除对象,则只能在堆上创建对象。


2
根据C++标准,如果你的类使用动态内存分配,并且在构造函数中抛出异常,为避免内存泄漏,必须释放内存。
在这里,你已将自己的new运算符定义为公共的,但delete是私有的。
因此编译器告诉你,给我访问delete运算符的权限,以便在构造函数中抛出任何异常时,防止内存泄漏。
如果你不定义delete运算符,则编译器也会报错并强制你定义它。

1
  • "1.错误的原因是什么?"

    sbi的回答很好。

  • "2.是否可以在不使用成员CreateInstance函数的情况下解决问题?"

    是的。创建私有析构函数。


2.的问题在于该类可以被继承,其析构函数可能会意外地被重新定义为公有。 - Marius
1
任何拥有私有析构函数的类均无法被继承。 - Alexey Malistov

0
调用类的 operator new,如果类构造函数抛出异常,则还会使用 delete class。
如果您的库不使用异常,可以从编译器中禁用异常 "-fno-exceptions",然后错误就不会再出现了。(在 Visual Studio 中位于 "C/C++"、"代码生成"、"启用 C++ 异常" > "否 (-fno-exceptions)")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接