接受新对象的宏
Macro that accept new object
在我的代码中,我有:
#define EV( event ) SendEvent( new event );
EV( evFormat );
但是我想在EV
宏中传递一个创建的对象,如:
CEvent *ev = new CEvent();
EV( ev );
这可能吗?因为我没有办法修改EV
宏
#define EV( event ) SendEvent( new event ); // Can't be changed.
宏强制每次调用SendEvent
都应该创建一个新的动态对象。你的问题不只是使用宏是愚蠢的,例如降低了你的源代码的可读性。此外,宏不允许您在调用之前创建对象,并且您不能更改宏;用你的话来说,"我没有办法修改EV
宏"。
因此解决方案很简单:
不要使用宏,直接使用SendEvent
,记住不要使用delete
。
当前编写EV
的方式,它将在每次调用时生成一个新对象。但是创建的对象不一定要与最终传递给SendEvent的对象类型相同。这是因为预处理器宏的文本性质和更复杂的表达式增加了一些技巧。想想看:
class dummy {
private:
static dummy* freeme;
public:
dummy() { freeme = this; }
static bool dofree() { delete freeme; return true; }
};
dummy* dummy::freeme;
CEvent *ev = new CEvent(this);
EV( dummy && dummy::dofree() ? ev : NULL );
这将展开,所以你正在运行的新不是一个CEvent,而是一个虚拟类…然后释放它,然后整个表达式求值为事件:
SendEvent( new dummy && dummy::dofree() ? ev : NULL );
(注意:使用?:不如逗号操作符好,所以这里浪费了一个NULL分支,实际上从来没有发生过。逗号操作符很好,但是预处理器宏对逗号有特殊的处理,这是不能使用逗号的情况之一。使其线程安全留给读者作为练习。)
为了使它"更干净",但仍然用EV
来表达…不用显式地提到SendEvent
,您就可以创建自己的宏:
#define EV2(event) EV( dummy && dummy::dofree() ? event : NULL )
…或者你可以直接使用SendEvent,因为它似乎可以完全满足你的需求。但这有什么好玩的呢?; p
更新:
正如@AlfPSteinbach指出的那样,将new
变成无op的一种更深奥但轻量级的方法是使用新的位置:
int dummy;
CEvent *ev = new CEvent(this);
EV( (&dummy) int ? ev : NULL );
现在扩展为:
SendEvent( new (&dummy) int ? ev : NULL );
你正在执行一个new,但是这次不用担心释放结果!因为我不完全确定这是否合适,特别是在线程的情况下,我提出了自己的问题:
在同一地址多次放置-new是否定义良好/合法?
完全可行,无需更改宏。这太冒险了。注意,您必须设置delete []
#include <memory>
struct CEvent {};
void SendEvent(CEvent*) {}
#define EV( event ) SendEvent( new event );
int main() {
char *cev = new char[sizeof(CEvent)];
CEvent* ev = (CEvent*)cev;
EV( (ev)CEvent );
ev->~CEvent();
delete [] cev;
}
http://ideone.com/您可能会泄漏内存,除非SendEvent从内部管理它,例如
void SendEvent(const Event *ev) {
doSendEvent(ev);
delete ev;
}
把这个放在一边,你试过了吗,应该可以的
EV(CEvent)
如果没有,可以为CEvent类重新定义operator new,这样上面的调用就可以工作了。
但是你的问题真的很不寻常。你确定你走的路对吗?
如果没有办法修改EV
宏,那么这是不可能的。你不能创建自己的宏,SendEvent( event );
代替?
更新:是否有可能#undef
原始宏,并提供您自己的定义?假设您只想要新的行为,您可以使用
#undef EV
#define EV( event ) SendEvent( event );
但是现在你需要用EV( new event )
代替原来的调用类型
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 重用对象与创建新对象
- C++,创建新对象时类的对象更改
- 运算符重载 += 添加新对象
- 如何在运行时在对象数组中动态追加新对象C++并打印它们
- 从使用概念定义的函数返回新对象
- 从 Rcpp 函数返回指向"新"对象的指针的正确方法
- 如何删除派生类中基类对象的新对象
- 有没有一种方法可以从函数中返回一个新对象或对现有对象的引用
- 为模板参数类型中的新对象分配内存
- 删除通过取消引用新对象初始化的对象
- C++ 实例化新对象时不接受继承方法默认参数值
- 有没有办法删除传递给函数"foo(新对象())"的对象?
- 将 Eigen::MatrixXd 转换为 arma::mat 并在新对象上制作副本
- 创建新对象并立即为其设置属性时出现编译器错误
- 如何异步销毁对象并立即分配一个新对象
- 删除传递给 C++ 中成员函数的新对象
- 具有构造函数的新对象数组,需要在C++中设置参数
- 我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?