c++ - 在 operator new 中访问一个对象

标签 c++ new-operator

我的 C++ 教授向我们展示了这个重载运算符 new 的示例(我认为这是错误的):

class test {
    // code
    int *a;
    int n;
public:
    void* operator new(size_t);
};

void* test::operator new(size_t size) {
    test *p;
    p=(test*)malloc(size);
    cout << "Input the size of array = ?";
    cin >> p->n;
    p->a = new int[p->n];
    return p;
}

这样对吗?

最佳答案

这绝对是“不对的”,因为它让我毛骨悚然。

因为 test 没有用户声明的构造函数,我认为它可以工作,前提是 test 的实例不是值初始化的(这会清除指针) .并且前提是你写了相应的operator delete

不过,这显然是一个愚蠢的例子——在重载的 operator new 中进行用户交互?如果在堆栈上创建了 test 的实例怎么办?还是复制的?或者在 C++03 中用 test *tp = new test(); 创建?还是安置新的?几乎没有用户友好性。

必须使用构造函数 来建立类不变量(例如“我有一个要使用的数组”),因为这是涵盖所有这些情况的唯一方法。所以像这样分配一个数组是应该在构造函数中完成的事情,而不是在 operator new 中。或者更好的是,使用 vector 代替。

就标准而言——我认为由于该类是非 POD 的,因此允许实现在调用 operator new 并将其返回给用户之间涂写所有数据,因此即使小心使用也不能保证有效。不过,我不完全确定。可以想象你的教授已经运行了它(也许很多年前他第一次编写类(class)时),如果是的话它可以在他的机器上运行。在此类的特定情况下,没有明显的理由说明为什么实现要对内存执行任何操作。

I believe that is "wrong" because he access the object before the constructor.

我认为你在这一点上也是正确的 - 将从 malloc 返回的指针转换为 test* 并且访问成员是 UB,因为类 test 是非 POD(因为它具有私有(private)非静态数据成员)并且内存不包含该类的构造实例。不过,同样,我没有理由立即想到为什么一个实现会想要做任何阻止它工作的事情,所以如果在实践中它将预期值存储在我机器上的预期位置,我并不感到惊讶。

关于c++ - 在 operator new 中访问一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4502728/

相关文章:

c# - 以最简单的方式实例化一个对象数组?

javascript - 当调用返回相同对象的函数时,无论是否作为构造函数调用,我是否应该使用 `new` ?

c++ - new(std::nothrow) int[n] 抛出异常

c++ - vector 破坏对象但不构造它们的替代品?

c++ - 将 child map 存储在基类 vector 中

c++ - 类型特征以匹配指向集合的指针

c++ - 是否可以完全禁用默认的 C++ new 运算符?

c++ - DirectX 9 中的简单剪辑

c++ - 修改顺序是否有助于 happens-before 关系?

Java - 我是否应该在 Setters 中使用 new() ?