私人运营商删除

时间:2012-09-21 18:36:00

标签: c++

  

可能重复:
  Public operator new, private operator delete: getting C2248 “can not access private member” when using new

http://efesx.com/2009/12/01/public-operator-new-and-private-operator-delete/

在本文中,我读到此代码应该出错:

#include <cstdlib>

struct Try {
        Try () { /* o/ */ }

        void *operator new (size_t size) {
            return malloc(size);
        }

    private:
        void operator delete (void *obj) {
            free(obj);
        }
};

int main () {
    Try *t = new Try();

    return 0;
}

我用gcc 4.7.1尝试了它:

Compilation finished with errors: source.cpp: In function 'int
main()': source.cpp:11:14: error: 'static void Try::operator
delete(void*)' is private source.cpp:17:22: error: within this context
source.cpp:11:14: error: 'static void Try::operator delete(void*)' is
private source.cpp:17:22: error: within this context source.cpp:17:10:
warning: unused variable 't' [-Wunused-variable]

在本文的评论中,我看到了这个链接 - Public operator new, private operator delete: getting C2248 "can not access private member" when using new

如果我unserstand它是正确的,它不会编译,因为编译器应该避免在构造函数通过调用适当的operator delete抛出异常的情况下的任何内存泄漏。但为什么这段代码编译和工作?

#include <cstdlib>

struct Try {
        void *operator new (size_t size) {
            return malloc(size);
        }

    private:
        void operator delete (void *obj) {
            free(obj);
        }
};

int main () {
    Try *t = new Try;

    return 0;
}

标准是否正确?

这段代码怎么样?

#include <cstdlib>

struct Try {
        void *operator new (size_t size) {
            return malloc(size);
        }

    private:
        void operator delete (void *obj) {
            free(obj);
        }
};

int main () {
    Try *t = new Try();

    return 0;
}

它不能用gcc 4.7.1编译。

这样的事情应该如何在标准库中实现?

Comeau没有编译所有这些例子:

"ComeauTest.c", line 15: error: function "Try::operator delete"
(declared at line 9) is inaccessible Try *t = new Try; ^

有人可以详细解释一下吗?

2 个答案:

答案 0 :(得分:2)

  • 似乎,你对第一个例子是正确的。

第二和第三个例子涉及POD类型。 initialization differences扮演角色。

  • 在第二个示例中,您的结构离开未初始化。没问题出现。

  • 相反,在第三个示例结构中, 进行初始化,因此您得到第一个案例。

修改

然后,operator new本身可以抛出异常。标准(c ++ 11 darft说):

  

如果new表达式通过抛出异常终止,它可能会   通过调用释放功能释放存储(3.7.4.2)。如果   assign type是非数组类型,分配函数的名称是   operator new和解除分配函数的名称为operator delete

有点不清楚,作者想要表达的是可能释放存储。如果 发布,它似乎是实现定义的。

无论如何,您可以尝试使用not-throwing new版本:

void *operator new (size_t size, std::nothrow_t) throw() {
    return malloc(size);
}

答案 1 :(得分:0)

编译器创建构造函数代码,如果构造函数代码抛出异常,也会涉及运算符 new delete 。因此,使用会自动创建删除的使用。

在第二个例子中,编译器知道你使用的默认构造函数从不抛出(我的猜测)..

不同的编译器以不同的方式工作,因为它们不同(队长)并且具有不同的优化功能和创建代码的技巧