全局新运算符重载
Global new operator overloading
我已经阅读了How_To_Find_memory_Leaks 中用于内存跟踪的new
和delete
过载
我定义了这些全球运营商:
inline void* __cdecl operator new( unsigned int size, const char *file, int line ) {
void* ptr = malloc( size );
AddTrack((DWORD)ptr, size, file, line);
return ptr;
}
inline void* __cdecl operator new( unsigned int size, void* ptr, const char *file, int line ) {
return ptr;
}
它适用于新的和新的[]运算符,但我在放置new(第二个)时遇到了问题。我的定义看起来像:
#define new new( __FILE__, __LINE__)
#define new(x) new( x, __FILE__, __LINE__)
它们分别工作。但当我尝试同时使用它们时,会出现错误。据我所知,他们互相替代。我知道我可以有一个具有可变参数数量的宏,如下所示:
#define new( ... ) new( __VA_ARGS__, __FILE__, __LINE__)
但我需要相同的宏,有参数和没有参数,所以这两行中的new
-都替换了right:
g_brushes = new Brush[ num_brushes ];
...
new( &g_brushes[i] )Brush(sides);
如果你决定走覆盖全局new的黑暗道路,你必须确保考虑以下所有场景:
new Foo; // 1
new Foo[10]; // 2
new (std::nothrow) Foo; // 3
new (p) Foo; // 4 - placement, not overridable
(Foo*) ::operator new(sizeof(Foo)); // 5 - direct invocation of the operator
除了最后一个之外,应该可以处理以上所有内容。颤抖
必要的技巧是宏应该以new
结束。当宏以new
结束时,可以将调用它的不同方式委托给new
本身。
以下是一种非线程安全的方法。定义一个类型来捕获调用的上下文,这样我们以后就可以在操作符中检索这个上下文
struct new_context {
new_context(const char* file, const int line)
: file_(file), line_(line) { scope_ = this; }
~new_context() { scope_ = 0; }
static new_context const& scope() { assert(scope_); return *scope_; }
operator bool() const { return false; }
const char* file_;
const int line_;
private:
static new_context* scope_;
};
接下来,定义覆盖以在调用之前创建一个new_context
临时
#define new new_context(__FILE__, __LINE__) ? 0 : new
使用三元运算符条件赋值来计算表达式,然后再将其委托给运算符new,请注意,这就是我们上面定义的operator bool
的用武之地。
然后在您的新覆盖(我将在这里使用标准C++98而不是MSC C++)中,您所要做的就是检索上下文:
void* operator new (std::size_t size) throw (std::bad_alloc) {
std::cout
<< "new"
<< "," << new_context::scope().file_
<< ":" << new_context::scope().line_
<< std::endl;
return 0;
}
这种方法将处理上述1-4
的所有情况,重要且容易被忽视的是,在4
的情况下,您的重载没有被调用,因为您无法替换新的放置(§18.4)。1.3),您仍然知道发生了新的放置,因为new_context
将被创建和销毁。
总之,您不需要修改new
运算符后面的内容,因此所有可能的语法都保持有效。另一点是,new_context
对象临时将保持活动状态,直到操作符参与的表达式结束,因此可以安全地从全局单例中获取它。
请参阅gcc示例适应MSC由读者决定
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 在 myVector 类中重载运算符 + 时出错
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 如何在 cpp 中重载运算符 +=?
- C++ 如何重载 [] 运算符并进行函数调用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 重载运算符有地址吗?
- 如何迭代重载运算符 [] 的类?
- 重载运算符与添加问题
- 模板基类中的重载运算符
- 如何调用用于重载运算符"<<"的 friend 函数?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 重载运算符<<采用谷歌 C++ 风格
- C++ 如何正确重载 + 运算符
- cout (<<) 重载运算符不打印减去的矩阵
- 如何在 c++ 中重载运算符 + 以便能够 whrite c_str = "smth" + c_str;
- 重载运算符*以获取对另一个类的实例的引用