定义我自己的新操作员
defining my own new operator
-------------------------------------------------1-------------------------------------------------
我正在为运行嵌入式Linux的ARM编译一个程序。我最初编写的程序是一个c++程序,所以代码中有一些operator new
和operator delete
。现在,要为典型的PC平台使用operator new
s和operator delete
s编译内容,我需要为链接器指定一个特定的参数(-lsdc++)。我不知道这到底是干什么的。
现在,如果我尝试在ARM交叉编译器中使用这个链接器选项,我会正确链接,但在运行时失败,并显示以下消息:
ld.so:dl deps.c:622:_dl_map_object_deps:断言`nlist>1'失败!
如果我省略了链接选项,我运行得很好。这看起来像是一个断言的失败,但这是我愿意冒险猜测的。有人能阐明这个错误或它可能的原因吗?
-----------------------------------------------2--------------------------------
我决定省略(-lsdc++)选项,并将所有类指针替换为指向堆栈上变量实例的指针。这很有效,但很明显很草率,因为这应该是学生们的榜样,我希望它干净。一个干净的方法是创建我自己的operator new
和operator delete
。。。但我实际如何使用自定义运算符并不明显。
以someClass * foo = new someClass(arg);
为例,这是三个步骤。
- 呼叫接线员new。为新的类实例分配一些内存
- 调用类构造函数
- 将类实例放入操作符new创建的内存位置
我不知道这些步骤的顺序。我不知道如何独立于在堆栈上创建该类型的新变量来调用类构造函数。我不知道如何将新的类变量从它开始的地方放入堆中。
首先,进行更正。你上面的创造陈述是两个步骤,而不是三个步骤;类构造函数直接应用于分配的内存区域,将其从"随机内存"转换为对象实例。不过,在其他方面是正确的。
重载运算符new相对简单。您不必在运算符new中调用类构造函数;该语言分别处理这些步骤。运算符new()本质上只是C++版本的malloc():
void *operator new(std::size_t sz) {
void *out = ::malloc(sz);
if (!out) throw new std::bad_alloc();
return out;
}
以上基本上模仿了真正的运营商new。您需要对此进行调整,以执行任何需要的特殊操作,从而使代码具有ARM功能。不过这里有一些魔法,所以要小心。运算符new()结束后,该语言将调用类构造函数,该构造函数对except是免费的。如果是这样,C++就需要释放运算符new()分配的内存(因为程序员没有对它的引用,因此无法自己释放它)。因此,在这种情况下,C++将神奇地触发运算符delete()。。。但前提是它能找到一个完美匹配的版本。
TL;DR:如果重载运算符new(),请始终重载运算符delete(),并确保它们在签名、范围等方面匹配。
- 没有为自己的结构调用列表推回方法
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 操作员C++的模棱两可的过载
- C++从对象自己的类中删除对象
- 使用 std::optional,而不是自己的结构
- 子轴围绕父轴而不是他自己的轴旋转
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- C++ 如何为自己的迭代器类从迭代器转换为const_iterator?
- 重载 + 自己的类和 std::string 的运算符
- 类无法访问自己的私有静态 constexpr 方法 - Clang bug?
- 是否可以在不填充自己的参数的情况下将模板函数作为参数传递?
- 如何访问模板参数自己的模板参数?
- 将矩阵乘以我自己的输入的向量
- 您应该在什么时候创建自己的异常类型
- 派生类是从基类继承 v 指针并仅使用它,还是也有自己的 v 指针?
- string1 == string2 和你自己的 for 循环比较有什么区别?
- 如何正确包含我自己的标头?
- 自己的自定义向量类. 内存重新分配
- 定义我自己的新操作员