当我尝试编译以下内容时:

#include <iostream>

class Test
{
public:
    void* operator new (size_t num);
    void operator delete (void* test);
    ~Test();
private:
    Test();
};

Test::Test()
{
    std::cout << "Constructing Test" << std::endl;
}

Test::~Test()
{
    std::cout << "Destroying Test" << std::endl;
}

void* Test::operator new (size_t num)
{
    ::new Test;
}

void Test::operator delete(void* test)
{
    ::delete(static_cast<Test*>(test));
}

int main()
{
    Test* test = new Test;
    delete test;
}

我得到:
$ g++ -o test test.cpp
test.cpp: In function ‘int main()’:
test.cpp:14: error: ‘Test::Test()’ is private
test.cpp:36: error: within this context

如果new是成员函数,为什么不能调用私有(private)构造函数?

编辑:
我的想法是创建一个只能使用完全标准语法在堆上实例化的类。我希望因为new是数据成员,它可以调用私有(private)构造函数,但是由于new不用于堆栈对象,因此您将不被允许在堆栈上创建对象。

最佳答案

我认为您对operator new的功能有误解。它不创建对象,而是为对象分配内存。编译器将在调用运算符new之后立即调用构造函数。

struct test {
   void * operator new( std::size_t size );
};
int main()
{
   test *p = new test;
   // compiler will translate this into:
   //
   // test *p = test::operator new( sizeof(test) );
   // new (static_cast<void*>(p)) test() !!! the constructor is private in this scope
}

new运算符的主要用法是有一个与系统默认分配器不同的内存分配器(通常是malloc),它的作用是返回未初始化的内存区域,编译器将在该内存区域调用构造函数。但是,构造函数是在写入新调用的作用域中分配了内存之后调用的(在这种情况下为main)。

验收通知单后

尚 Unresolved 问题的完整解决方案:如何强制类(class)用户在堆中实例化?是使构造函数私有(private)化并提供工厂函数,如其他一些答案所示(如villintehaspam所示)。

09-25 18:30
查看更多