我正在尝试解决我的程序的一部分,它有一个#define new。一切正常,直到我尝试创建一个覆盖新运算符的类模板,当我得到错误时:
C:\Define_New_problem\main.cpp:18: error: expected type-specifier before 'dPushMemManFileLine'
C:\Define_New_problem\main.cpp:18: error: expected ';' before 'dPushMemManFileLine'
C:\Define_New_problem\main.cpp:21: error: expected ';' before '}' token
Process terminated with status 1 (0 minutes, 0 seconds)
使用MinGW。 (简化)代码如下:
#include <iostream>
#define new dPushMemManFileLine( __FILE__, __LINE__ ) ? 0 : new
using namespace std;
static const int NUM_NEW_STACK_SIZE = 256;
static struct { const char* filename; unsigned int line; } g_NewStackMemDebug[NUM_NEW_STACK_SIZE];
static int g_CurStack = -1;
template <class T>
class mypair {
private:
int a, b;
public:
mypair (int first, int second)
{a=first; b=second;}
static void* operator new(size_t size)
{
}
};
int dPushMemManFileLine( const char* filename, unsigned int line )
{
if(g_CurStack >= NUM_NEW_STACK_SIZE )
return 0;
g_CurStack++;
g_NewStackMemDebug[g_CurStack].filename = filename;
g_NewStackMemDebug[g_CurStack].line = line;
return 0; // needed for the new passthrough trick
}
int main()
{
cout << "Hello world!" << endl;
return 0;
}
有谁知道如何解决这个问题?
答案 0 :(得分:9)
#define
。关键字。强> 请不要。它只会产生问题。 #define
将所定义单词的所有出现替换为您定义的单词,因此在#define
'd new
展开后,运算符重载如下所示:
static void* operator dPushMemManFileLine( __FILE__, __LINE__ ) ? 0 : new(size_t size)
{
}
Uuups ....
当然问题仍然存在,你为什么这样做?
答案 1 :(得分:3)
我认为当您展开第new
行中的static void* operator new(size_t size)
时,错误会变得非常明显:
class mypair {
static void* operator dPushMemManFileLine( __FILE__, __LINE__ ) ? 0 : new(size_t size)
{ }
};
在关键字上使用#define
是一个危险的游戏:)
答案 2 :(得分:1)
如上所述,错误即将发生,因为您的#define new
也会在operator new
展开。
为了解决您的问题,我建议您尝试以下方法;这将有助于您避免使用宏:
//overload new with LINE & FILE and call the function inside
void* operator new (size_t size, const char *FILE, const unsigned int LINE)
{
dPushMemManFileLine(FILE, LINE);
return malloc(size);
}
//overload the default new operator and throw something vague
void* operator new (size_t size)
{
class BadNewUsed {} bad;
throw bad; // throw it; since we can't catch it at compile time
}
用法:
int *pi = new(__LINE__, __FILE__) int; // ok
double *pd = new double; // throws BadNewUsed out of your code,
您只需付出努力就可以更正new
的来电,直到它不throw
为止。你也可以用一种简单的技术快速完成。只是做
#define new abcd // to get compilation error wherever new is present
现在,将new
的每个来电替换为NEW
。不要替换operator new
实现。然后呢,
#define NEW new( __FILE__, __LINE__)
编译代码。请注意,此宏用法用于调试目的并使事情变得快速。我不建议在生产代码中使用它。
如果您不想使用templates
等宏,也可以使用NEW
实现此目的。
template<typename T>
T* NEW (const char* FILE, const unsigned int LINE)
{
dPushMemManFileLine(FILE, LINE);
return new T; // can use default version or any overloaded version of 'new'
}
用法:
int *p = NEW<int>(__FILE__, __LINE__);