【问题标题】:c++ - overloading operator newc++ - 重载运算符new
【发布时间】:2016-10-07 09:28:25
【问题描述】:

我对运算符重载 new 和 delete 有点困惑。 我写了一些测试:

#include <iostream>

using namespace std;

class Test
{
    public :

    Test()
    {
        cout << "Test - ctor" <<endl;
    }

    ~Test()
    {
        cout << "Test - dtor" <<endl;
    }

    Test(const Test& t)
    {
        cout << "Test - copy ctor" <<endl;
    }

    Test& operator = (const Test& t)
    {
        cout << "Test - assiment operator" <<endl;
    }

    void* operator new(size_t size)
    {
        cout << "Test - operator new" <<endl;
        return NULL;
    }

    void print()
    {
        cout << "print" << endl;
    }
};


int main()
{
   Test* t = new Test();
   t->print();
   return 0;
}

输出是:

Test - operator new                                                                                                                                                                                
Test - ctor                                                                                                                                                                                        
print  

现在,如果我从 "new" 返回 "NULL" ,为什么我调用 print 函数时程序不会崩溃? 谢谢。

【问题讨论】:

  • 这与过载无关,它是常规的未定义行为。试试Test* t = nullptr; t-&gt;print(); 看看会发生什么(或没有)。
  • UB 和 UB 一样。

标签: c++ operator-overloading new-operator


【解决方案1】:

因为print() 实际上并不需要它的类Test 的任何东西。它所做的只是向stdout 打印一条消息。记住t-&gt;print();print(t);是一样的,你的函数签名其实是:

void print(Test* t);

但这都是编译器为你完成的。

t 只是没有在该方法中使用,因此您(不)幸运,因为它运行了。不过,这仍然只是普通的未定义行为。

如果你绝对希望看到事情崩溃和燃烧,那么稍微改变你的班级:

class Test
{
    public :

    Test() : x(0)
    {
        cout << "Test - ctor" <<endl;
    }

    ~Test()
    {
        cout << "Test - dtor" <<endl;
    }

    Test(const Test& t)
    {
        cout << "Test - copy ctor" <<endl;
    }

    Test& operator = (const Test& t)
    {
        cout << "Test - assiment operator" <<endl;
    }

    void* operator new(size_t size)
    {
        cout << "Test - operator new" <<endl;
        return NULL;
    }

    void print()
    {
        cout << "print" << x << endl;
    }

private:
    int x;
};

【讨论】:

  • 谢谢。现在我明白了。
【解决方案2】:

这个具体现象与你的operator new函数无关。

通过 NULL 指针调用成员函数的行为是未定义。您的结果是这种未定义行为的表现。

它恰好适用于您的特定情况(可能是因为您的类只是一个函数包)。

(现在最好使用nullptr,而不是老式且不完全正确的NULL。)

【讨论】:

  • 这是一个更好的答案,比公认的充满错误事实和糟糕建议的答案。
  • @MikeVine 我的回答中没有看到任何“建议”。如果您不同意答案中的某些内容,请发表评论。
  • @GillBates ...您的函数签名实际上是...不,它不是。 如果你想看到事情崩溃和燃烧不,他们不会。未定义的行为是未定义的。原始的或您的新的可能会或可能不会崩溃,这取决于许多不同的事情,包括可能的月相。它的未定义。这个答案说明了这一点。未定义就是这样。弄清楚为什么在 UB 之后会发生某些事情几乎从来都不是正确的事情。
  • @MikeVine 实际上,是的。虽然您关于未定义行为的案例是正确的,但在这种情况下,代码仅向 OP 显示他们希望的“崩溃”。我从来没有说过要依赖它,但是,在每个主要编译器上,行为都是完全相同的。这是OP想要看到的。您不能依赖它,因为它是未定义的,但就机器指令而言,没有未定义的行为之类的东西。另外,评论我的答案,而不是这个,不要污染芭丝谢巴的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多