众所周之, 在MFC Debug 程序由VC生成的cpp中 new 是进行了宏定义的
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
这样 分配内存的语句类似 int* pn = new int; 的就会被最终替换为 int* pn = new(THIS_FILE, __LINE__) int; 而被执行现在我想要重载new函数
      void* AFX_CDECL operator new(size_t nSize, unsigned long dwMyData)
在某引些代码中使用这个重载的new函数
比如:
int* pn = new int;        // 调用VC定义的new
DWORD* pn1 = new DWORD;   // 这一句我想使用我重载的new函数, 那么这里的调用就应该是 DWORD* pn1 = new(dwMyData) DWORD;但现在问题来了,我使用DWORD* pn1 = new(dwMyData) DWORD;后发现编译不通过, 这是因为DEBUG版本宏定义使 new 被替换为 DEBUG_NEW, 最终这句代码变为
DWORD* pn1 = new(THIS_FILE, __LINE__)(dwMyData) DWORD;
当然就出错了我现在就想怎么能在 DEBUG版本下 能既支持VC定义的new函数, 又支持我定义的new函数呢?现在有一个觉得不大好的方法,就是写了一个 defMyNew.h
///////////////////////////////////
// defMyNew.h
#ifndef __DEFMYNEW_H__
#define __DEFMYNEW_H__void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine, unsigned long dw)
{
// 我的实现代码
}template<class T> T* MyNew(T n)
{
return new(__FILE__, __LINE__, 0) T;
}#endif // __DEFMYNEW_H__
在使用时这样写
//////////////////////////////////////
// Test.cpp
#include "stdafx.h"
#include "Test.h"
#include "defMyNew.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endifvoid Test()
{
  int* pn = new int;
  int* pn1 = MyNew(int())
  DWORD* pdw = MyNew(DWORD());
}这样通过函数模板就可以兼容两个new函数的使用
但这种写法自已都觉得很怪异
希望大家发表一下各自的高见, 能更好的实现我的要求

解决方案 »

  1.   

    new原型不对void *__cdecl operator new(
       size_t count
    );
    void *__cdecl operator new(
       size_t count, 
       void * object
    ) throw();
    void *__cdecl operator new(
       size_t count, 
       const std::nothrow_t&
    ) throw();
      

  2.   

    首先来说不管怎么重载new返回值都是void* 编译器会处理好类型转化的
    所以做模板没有必要
    如果真想在debug版本中用自己的new的话,直接用宏替换掉DEBUG_NEW这个 换成原来的new就可以了还有一点 默认的new是线程安全的
      

  3.   

    /////////////////////////////////// 
    // defMyNew.h 
    #ifndef __DEFMYNEW_H__ 
    #define __DEFMYNEW_H__ 
    #pragma warning(disable: 4800)
    #pragma push_macro("new")
    #undef new
    void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine, unsigned long dw) 

    // 我的实现代码 
    } template <class T> T* MyNew(T n) 

    return new(__FILE__, __LINE__, 0) T; 
    #pragma pop_macro("new")
    #pragma warning(default: 4800)
    #endif // __DEFMYNEW_H__ 
    ////////////////////////////////////// 
    // Test.cpp 
    #include "stdafx.h" 
    #include "Test.h" #ifdef _DEBUG 
    #undef THIS_FILE 
    static char THIS_FILE[]=__FILE__; 
    #define new DEBUG_NEW 
    #endif 
    #include "defMyNew.h" // 换一个位置,放到#define new...的后面void Test() 

      int* pn = new int; 
      int* pn1 = MyNew(int()) 
      DWORD* pdw = MyNew(DWORD()); 
    }
      

  4.   


    如果是这样
    int* pn = new int; 也被替换为我重载的new了, 像是不符合我的要求吧
    做成模板只是让我的重载new不受Test.cpp宏定义的影响而不得不用的
      

  5.   

    jameshooo 
    你加上
    #pragma pop_macro("new") 
    #pragma warning(default: 4800) 
    这些的目的是什么呢?加上后,基本的方法还是我的那个方法呀
      

  6.   

    #pragma pop[push]_macro("new") -----> 告诉编译器把旧的new符号定义出栈[压栈],相当于保存旧的符号定义,自己使用新定义,使用完毕恢复原始状态
    #pragma warning(disable[default]: 4800) -----> 消除编译器的一个类型转换警告而已,可以不使用
      

  7.   

    不用吧? 因为我是把 #include "defMyNew.h"放到宏定义之前的呀, 所以它是会调用我定义的new函数
    没有必要加上这些吧?
    不明白,解释一下
      

  8.   

    new 重载不是这么用的,如果你非要这样,那肯定怪怪的。楼主无非就是区别两种new,那么直接定义mynew全局函数,再替换掉要区别的new就可以啦。
    干嘛弄得这么乱啊。
      

  9.   


    new 除了内存分配外,还会自动地调用创建对象的构造函数
    如果我定义mynew全局函数, 那只能实现内存的分配,不能调用对象的构造函数, 这和new的功能不符吧?
      

  10.   

    zhoujianhei,
    你看我的实现就是定义了一个函数MyNew, 
    使用模板的原因就是为了把要创建的类型传到MyNew里面
    在里面使用真正的new 来分配内存,调用对象构造函数
      

  11.   

    何苦呢,要程序调用你的new,你的new又去调用系统的new,为何要多这个步骤?
    调用构造函数也很简单,假设你在栈上构造一块内存用于CYourClass,要调用CYourClass的构造函数,你可以这样写:
    BYTE buf[sizeof(CYourClass)]; // 栈上的内存块,或者用全局的也可以 BYTE* buf = new BYTE[sizeof(CYourClass)];
    ::new(buf) CYourClass(); // 这句就是调用构造函数
    CYourClass* p = (CYourClass*)buf; // 现在可以用p了