定义我自己的新运算符

时间:2012-10-10 01:11:55

标签: c++ embedded new-operator

------------------------------------------ 1 ---- --------------------------------------

我正在为运行嵌入式Linux的ARM编译程序。我最初将程序编写为c ++程序,因此代码中有一些operator newoperator delete。现在,要为典型的PC平台编译operator newoperator delete s的东西,我需要为链接器指定一个特定的参数(-lddc ++)。我不确切知道这是做什么的。

现在,如果我尝试将此链接器选项与我的ARM交叉编译器一起使用,我正确链接,但是在运行时我使用此消息失败:

  

ld.so检测到不一致:dl-deps.c:622:_dl_map_object_deps:断言`nlist> 1'失败了!

如果我省略链接选项,我运行正常。这看起来像是一个断言失败,但这就是我愿意冒险的猜测。任何人都可以对这个错误或其可能的原因有所了解吗?

----------------------------------------------- 2 ------------------------------------

我决定省略(-lstdc ++)选项,并将所有类指针替换为指向堆栈上变量实例的指针。这是有效的,但它显然是草率的,因为这应该是学生的一个例子,我希望它干净。一个干净的方法是创建我自己的operator newoperator delete ...但是我实际上如何使用自定义运算符并不明显。

举个例子,someClass * foo = new someClass(arg);这是三个(?)步骤。

  1. 调用operator new。为新的类实例分配一些内存。
  2. 调用类构造函数。
  3. 将类实例放入operator new
  4. 创建的内存位置

    我不知道这些步骤的顺序。我不知道如何独立于在堆栈上创建该类型的新变量来调用类构造函数。而且我不知道如何将新的类变量从它开始的任何地方放入堆中。

1 个答案:

答案 0 :(得分:1)

首先,纠正。你上面的创作声明是两步,而不是三步;类构造函数直接应用于分配的内存区域,以将其从“随机内存”转换为对象实例。否则就对了。

重载operator new相对简单。您不必在operator new中调用类构造函数;该语言分别处理这些步骤。 operator new()本质上只是C ++的malloc()版本:

void *operator new(std::size_t sz) {
    void *out = ::malloc(sz);
    if (!out) throw new std::bad_alloc();
    return out;
}

以上基本上模仿了真实的操作员新手。您需要调整它以执行使您的代码具有ARM功能所需的任何特殊操作。这里有一些魔力,所以要小心。在运算符new()结束之后,该语言将调用您的类构造函数,该构造函数可以免费使用。如果是这样,C ++需要释放运算符new()分配的内存(因为程序员没有对它的引用,因此无法自己释放它)。因此,C ++会在这种情况下神奇地触发operator delete()......但前提是它能找到一个完美匹配的版本。

TL; DR:如果重载operator new(),也总是重载operator delete()并确保它们在签名,范围等方面匹配。