公共运营商新的私人运营商删除:使用新的时候获取C2248“无法访问私人会员”

时间:2009-11-30 14:12:25

标签: c++ compiler-errors overloading

一个类重载了运算符newdeletenew是公开的,delete是私有的。

构造此类的实例时,出现以下错误:

pFoo = new Foo(bar)

example.cpp(1):错误C2248:'Foo:operator delete':无法访问类'Foo'中声明的私有成员

但是这里没有调用delete,所以在编译器的扭曲思想中发生了什么? :)

  1. 错误的原因是什么?
  2. 是否可以在不诉诸成员CreateInstance功能的情况下解决问题?

5 个答案:

答案 0 :(得分:27)

执行new Foo()时会发生两件事:调用第一个operator new来分配内存,然后调用Foo的构造函数。如果该构造函数抛出,因为您无法访问已分配的内存,C ++运行时将通过将其传递给相应的operator delete来处理它。这就是为什么你总是必须为你写的每个operator delete实现一个匹配的operator new,这就是为什么它需要被访问。

作为一种出路,你可以将它们都设为私有,并从公共成员函数(如operator new)中调用create()

答案 1 :(得分:3)

检查this。在其中一个较低的段落中,它表示new要求删除是可访问的。基本上它说,你只能在堆上创建对象,如果你也可以再次删除它们。

答案 2 :(得分:2)

根据C ++标准,当您拥有动态内存分配的类并且在构造函数中引发异常时,必须释放内存以避免内存泄漏。

在这里,您已将自己的新运营商定义为公共运营商,但删除是私有运营商。

所以编译器告诉你,让我可以访问delete运算符 如果在构造函数中引发任何异常,则防止内存泄漏。

如果您没有定义删除操作符,那么编译器也会给出错误并强制您定义它。

答案 3 :(得分:1)

  • “1。错误的原因是什么?”

    sbi的答案很好。

  • “2.是否可以在不诉诸成员CreateInstance函数的情况下解决问题?”

    是。创建私有析构函数。

答案 4 :(得分:0)

如果类构造函数引发异常,则在类上调用new运算符也将使用删除类。

如果您的库不使用异常,则可以从编译器“ -fno-exceptions”禁用异常,这样就不会再出现错误。 (在Visual Studio中位于“ C / C ++”,“代码生成”,“启用C ++异常”>“否(-fno-exceptions)”下)