'new' : function does not take 3 parameters(转载)

转载自:http://www.cnblogs.com/carekee/articles/2038116.html

VC GDI+: error C2660: 'new' : function does not take 3 parameters

今天在用GDI+写程序时,有
bmp = new Bitmap(L"E:\\1.png");
用VC6 SP6或VS2005编译错误为error C2660: 'new' : function does not take 3 parameters
这是VC的一个BUG,微软至今还没有解除。
解决办法如下:
法一:在该CPP文件开头部分注释掉#define new DEBUG_NEW
#ifdef  _DEBUG
//#define new DEBUG_NEW
#undef  THIS_FILE
static  char THIS_FILE [] = __FILE__;
#endif
建议法二:在GdiplusBase.h文件中class GdiplusBase中添加如下代码
 //
 void * (operator new)(size_t nSize, LPCSTR lpszFileName, int nLine)
 {
  return DllExports::GdipAlloc(nSize);
 }
 
 void operator delete(void* p, LPCSTR lpszFileName, int nLine)
 {
  DllExports::GdipFree(p);
 }
 //
下面是转载文章,作者:billdavid
不让用盗版,遂准备逐一将各软件要么换成开源的,要么就自己写,看了看,就数Acdsee最简单了(有些高级功能根本用不着),行,从这个入手吧。
需求分析:基本的图片查看功能,图片格式转换功能,基本的图形变换功能。
技术可行性分析:MS提供的GDI
+已经提供了比较专业的图形显示、格式转换功能,而且简单易用。
....

OK,就绪,开始干吧。

但是在程序编写的过程中,有条错误信息让我很不解。程序中有如下语句:
bmPhoto
 = new Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB );
每次DEBUG编译的时候总是报告如下的错误:
error C2660
: 'new' : function does not take 3 parameters
开始以为是Bitmap的构造函数的问题,但是查了一下,Bitmap明明有个构造函数:
Bitmap
(IN INT width,
       IN INT height,
       IN PixelFormat format = PixelFormat32bppARGB);
那会是什么问题呢?上网讨论了一下,最终将问题锁定在MFC程序中的这样一个宏定义上:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
这几行从来都不会引起我们注意的代码有什么问题呢?为什么会使得我们的代码报告如上所述的编译错误呢?
让我们来看看DEBUG_NEW的定义(在afx.h中):
#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)

// Memory tracking allocation
void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
#define DEBUG_NEW new(THIS_FILE, __LINE__)
#if _MSC_VER >= 1200
void AFX_CDECL operator delete(void* p, LPCSTR lpszFileName, int nLine);
#endif
看到这里你可能会想,new被define成了DEBUG_NEW,而后者又被define成了new(...),这不是成了个循环?非也。由于afx.h早于任何其它头文件被包含(stdafx.h包含afxwin.h,afxwin.h又包含了afx.h,而MFC要求我们在任何有效代码之前包含stdafx.h,当然,这不是必须的),所以DEBUG_NEW的定义早于后面的#define new DEBUG_NEW,也就是说这个define只对后面的代码有效,对前面已经include了的afx.h中的代码是无效的。

上面只是题外话,现在回到正题。
MFC重载
operator new,是为了方便定位内存泄漏,重载后的operator new会记录下所分配的每块内存对应的__FILE__和__LINE__信息。一般来讲,标准的operator new的声明如下:
void *__cdecl operator new(size_t);
即它只有一个参数,只接收一个size信息。我们的如下代码
int* pi = new int; // the same as int* pi = new int(); or int* pi = new int[1];
等价于
int* tpi = (int*)operator new(sizeof(int)); // attention: this line cannot pass compilation if you have define DEBUG_NEW
int* pi = tpi;
同理,定义DEBUG_NEW前,文章开头报错的这条语句:
Bitmap
* bmPhoto = new Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB );
等价于
Bitmap
* tbmPhoto = (Bitmap*)operator new(sizeof(Bitmap));
tbmPhoto->Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB ); // initialize variable
Bitmap* bmPhoto = tbmPhoto;
但是现在,由于DEBUG_NEW使用的是被重载的operator new
void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
上述代码等价于:
Bitmap
* tbmPhoto = (Bitmap*)operator new(sizeof(Bitmap), __FILE__, __LINE__);
tbmPhoto->BitmapBitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB ); // initialize variable
Bitmap* bmPhoto = tbmPhoto;
回过头来看gdiplus.h中的operator new的声明(在GdiplusBase.h中):
class GdiplusBase
{

public
:
    void
 (operator delete)(void* in_pVoid)
    {

       DllExports::GdipFree(in_pVoid);
    }

    void
* (operator new)(size_t in_size)
    {

       return
 DllExports::GdipAlloc(in_size);
    }

    void
 (operator delete[])(void* in_pVoid)
    {

       DllExports::GdipFree(in_pVoid);
    }

    void
* (operator new[])(size_t in_size)
    {

       return
 DllExports::GdipAlloc(in_size);
    }
};

它重载了operator new,并且没有提供一个可以容纳3个参数的operator new,同时基于这样一个事实:
不同命名域(指全局命名空间与有名命名空间之间,父类与子类,全局与类内部)内进行重载时,下一级的命名空间会覆盖掉上一级的定义,除非显示调用上一级的定义。
因此,全局的重新定义的
operator new并不能用于Bitmap类。也正因为这一原因,编译器会报告:
Bitmap
* tbmPhoto = (Bitmap*)Bitmap::operator new(sizeof(Bitmap), __FILE__, __LINE__);
error C2660: 'new' : function does not take 3 parameters
知道了这一点,要修正这一问题,只需给
class GdiplusBase多重载几个operator new即可。修正后的class GdiplusBase如下:
#ifdef _DEBUG

namespace
 Gdiplus
{

    namespace
 DllExports
    {

        #include <GdiplusMem.h>
    };

    #ifndef _GDIPLUSBASE_H
    #define _GDIPLUSBASE_H
    class GdiplusBase
    {

        public
:
            void
 (operator delete)(void* in_pVoid)
            {

                DllExports::GdipFree(in_pVoid);
            }


            void
* (operator new)(size_t in_size)
            {

                return
 DllExports::GdipAlloc(in_size);
            }


            void
 (operator delete[])(void* in_pVoid)
            {

                DllExports::GdipFree(in_pVoid);
            }


            void
* (operator new[])(size_t in_size)
            {

                return
 DllExports::GdipAlloc(in_size);
            }


            void
 * (operator new)(size_t nSize, LPCSTR lpszFileName, int nLine)
            {

                return
 DllExports::GdipAlloc(nSize);
            }


            void
 operator delete(void* p, LPCSTR lpszFileName, int nLine)
            {

                DllExports::GdipFree(p);
            }

        };

    #endif // #ifndef _GDIPLUSBASE_H
}
#endif // #ifdef _DEBUG
OK,问题已解决,其实这只是个重载operator new的问题,但这个问题由于DEBUG_NEW这个不起眼的宏,倒还真变得有点复杂。

最后总结一下,在进行
operator new重载时应注意:
1.new operator是不可以重载的,可以重载的是operator newnew operator 首先调用 operator new,然后调用构造函数(如果有的话)。new operator的这个行为是不可以重载的,可以重载的仅仅是operator new,也就是内存分配。
2.重载operator new是一件必须十分小心的事情,在编写MFC程序或者你所编写的系统重载了全局的operator new时,尤其需要注意,同时应注意所有的#include头文件最好添加在所有define之前,以免造成受到后续对new的重定义的影响。你可以尝试在你的MFC程序的#define new DEBUG_NEW一句之后,添加#include <vector>,你会收到一大堆莫名奇妙的错误提示(DEBUG编译时才有),这正是由于#define new DEBUG_NEW和后面的static char THIS_FILE[] = __FILE__;造成的影响。
3.operator new/delete在性质上类似于静态函数,你可以直接通过类名来访问它们。
4.理解了operator new的基本概念,要理解头文件NEW中的placement new/delete的实现也就不是什么难事了,头文件NEW中的placement new/delete的实现如下:
#ifndef __PLACEMENT_NEW_INLINE
#define __PLACEMENT_NEW_INLINE
inline void *__cdecl operator new(size_t, void *_P)
    {
return (_P); }
#if     _MSC_VER >= 1200
inline void __cdecl operator delete(void *, void *)
    {
return; }
#endif
#endif

附:
(
转贴)C++的各种new简介

1.new T

第一种
new最简单,调用类的(如果重载了的话)或者全局的operator new分配空间,然后用类型后面列的参数来调用构造函数,用法是
new TypeName(initial_args_list).
如果没有参数,括号一般可以省略.例如

int *p=new int;
int
 *p=new int(10);
int
 *p=new foo("hello");

通过调用delete来销毁:
delete
 p;

2.
 new T[]
这种new用来创建一个动态的对象数组,他会调用对象的operator new[]来分配内存(如果没有则调用operator new,搜索顺序同上),然后调用对象的31m默认构造函数初始化每个对象用法:
new
 TypeName[num_of_objects];
例如
int *p= new int[10];
销毁时使用operator delete31m[]

3.
new()T 和new() T[]
这是个带参数的new,这种形式的new会调用operator new(size_t,OtherType)来分配内存,这里的OtherType要和new括号里的参数的类型兼容,这种语法通常用来在某个特定的地址构件对象,称为placement new,前提是operator new(size_t,void*)已经定义,通常编译器已经提供了一个实现,包含<new>头文件即可,这个实现只是简单的把参数的指定的地址返回,因而new()运算符就会在括号里的地址上创建对象.
需要说明的是,第二个参数不是一定要是void*,可以识别的合法类型,这时候由C++的重载机制来决定调用那个operator new.

当然,我们可以提供自己的operator new(size_,Type),来决定new的行为,比如
char data[1000][sizeof(foo)];
inline
 void* operator new(size_t ,int n)
{

        return
 data[n];
}


就可以使用这样有趣的语法来创建对象:
foo *p=new(6) foo(); //把对象创建在data的第六个单元上的确很有意思
标准库还提供了一个nothrow的实现:
void
* operator new(std::size_t, const std::nothrow_t&) throw();
void
* operator new[](std::size_t, const std::nothrow_t&) throw();

就可以实现调用new失败时不抛出异常
new(nothrow) int(10);
// nothrow 是std::nothrow_t的一个实例

placement new 创建的对象不能直接delete来销毁,而是要调用对象的析够函数来销毁对象,至于对象所占的内存如何处理,要看这块内存的具体来源.

4.
 operator new(size_t)
这个的运算符分配参数指定大小的内存并返回首地址,可以为自定义的类重载这个运算符,方法就是在类里面声明加上
void *operator new(size_t size)
{

        //在这里分配内存并返回其地址
}
无论是否声明,类里面重载的各种operator newoperator delete都是具有static属性的.

一般不需要直接调用operator new,除非直接分配原始内存(这一点类似于C的malloc),在冲突的情况下要调用全局的operator加上::作用域运算符:
::
operator new(1000); // 分配1000个31m字节

返回的内存需要回收的话,调用对应的operator delete

5.
operator new[](size_t)

这个也是分配内存,,只不过是专门针对数组,也就是new T[]这种形式,当然,需要时可以显式调用

6.operator new(size_t size, OtherType other_value)
operator new[](size_t size, OtherType other_value)
参见上面的new()

需要强调的是,new用来创建对象并分配内存,它的行为是不可改变的,可以改变的是各种operator new,我们就可以通过重载operator new来实现我们的内存分配方案.

参考资料:
1.PRB: Microsoft Foundation Classes DEBUG_NEW Does Not Work with GDI+. http://support.microsoft.com/default.aspx?scid=kb;en-us;317799
2.VC++6.0中内存泄漏检测. http://blog.vckbase.com/bruceteen/archive/2004/10/28/1130.aspx
3.More Effective C++. Item 8: Understand the different meanings of new and delete.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
服务器端利用 PHP插件 生成标签云数据,页面用 flash 3D效果展示标签,效果很爽的,放在自己博客格外吸引眼球。 查看效果: http://www.roytanck.com/about-my-themes/donations/ 下面是详细: ------------------------------------------------------------ === Plugin Name === Contributors: weefselkweekje Donate link: http://www.roytanck.com/about-my-themes/donations/ Tags: tag cloud, flash, sphere, categories, widget Requires at least: 2.3 Tested up to: 2.6.3 Stable tag: 1.17 WP-Cumulus displays your tags and/or categories in 3D by placing them on a rotating sphere. == Description == WP-Cumulus allows you to display your site's tags, categories or both using a Flash movie that rotates them in 3D. It works just like a regular tags cloud, but is more visually exciting. Clicking the tags can be a little hard (depending on your speed setting) but does take you to the appropriate page :). The sources code for the Flash movie are available from wordpress.org. == Installation == = Installation = 1. Make sure you're running WordPress version 2.3 or better. It won't work with older versions. Really. 1. Download the zip file and extract the contents. 1. Upload the 'wp-cumulus' folder to your plugins directory (wp-content/plugins/). 1. Activate the plugin through the 'plugins' page in WP. 1. See 'Options->WP Cumulus' to adjust things like display size, etc... = In order to actually display the tag cloud, you have three options. = 1. Create a page or post and type [WP-CUMULUS] anywhere in the content. This 'tag' will be replaced by the flash movie when viewing the page. 1. Add the following code anywhere in your theme to display the cloud. `<?php wp_cumulus_insert(); ?>` This can be used to add WP Cumulus to your sidebar, although it may not actually be wide enough in many cases to keep the tags readable. 1. The plugin adds a widget, so you can place it on your sidebar through 'Design'->'Widgets'. The widget uses a separate set of settings, so it's possible to have different background colors, sizes, etc. == Frequently Asked Questions == = My theme/site appears not to like this plugin. It's not displaying correctly. = There are a number of things that may prevent WP-Cumulus from displaying or cause it to display a short message about how it needs the Flash plugin. * In 99% of all cases where this happens the issue is caused by markup errors in the page where the plugin is used. Please validate your blog using [validator.w3.org](http://validator.w3.org) and fix any errors you may encounter. * Older versions had issues with PHP 5.2 (or better). This has been fixed, so please upgrade to the latest version. * The plugin requires Flash Player 9 or better and javascript. Please make sure you have both. * There have been some cases where WordPress' Automatic Plugin Upgrade feature breaks the plugin. After upgrading the plugin the Flash movie would be corrupt for some users. If this happens to you, please try disabling and reinstalling the plugin (through FTP). = Hey, but what about SEO? = I'm not sure how beneficial tag clouds are when it comes to SEO, but just in case WP Cumulus outputs the regular tag cloud (and/or categories listing) for non-flash users. This means that search engines will see the same links. = I'd like to change something in the Flash movie, will you release the .fla? = As of version 1.12 the source code is available from wordpress.org under the GP license. Click "other versions" and get the developer version. = Some of my tags occasionally hit the sides of the movie and are cropped = If this happens you should change the aspect for the movie to make it wider. This can be done by increasing the width, but also by decreasing the height. Both will make the movie 'more landscape' giving long tags more room. = Some characters are not showing up = Because of the way Flash handles text, only Latin characters are supported in the current version. This is due to a limitation where in order to be able to animate text fields smoothly the glyphs need to be embedded in the movie. The Flash movie's source code is available for download through Subversion. Doing so will allow you to create a version for your language. There's a text field in the root of the movie that you can use to embed more characters. If you change to another font, you'll need to edit the Tag class as well. More info [here](http://www.roytanck.com/2008/08/04/how-to-add-more-characters-to-wp-cumulus/). = When I click on tags, nothing happens. = This is usually caused by a Flash security feature that affects movies served from another domain as the surrounding page. If your blog is http://yourblog.com, but you have http://www.yourblog.com listed as the 'WordPress address' under Settings -> General this issue can occur. In this case you should adjust this setting to match your blog's actual URL. If you haven't already, I recommend you decide on a single URL for your blog and redirect visitors using other options. This will increase your search engine ranking and in the process help solve this issue :). = I'm not using WordPress... = * Steve Springett has ported this to Movable Type. More info over on [his site](http://www.6000rpms.com/blog/2008/04/04/flash-tag-cloud-for-mt-4.html). * Michael Robinson has ported WP-Cumulus to RapidWeaver, see his tutorial [here](http://pagesofinterest.net/mikes/blog_of_interest_files/tag_cloud.php). * Amanda Fazani managed to get Cumulus working on Blogger. More info on Blogumus [here](http://www.bloggerbuster.com/2008/08/blogumus-flash-animated-label-cloud-for.html). * Yannick Lejeune has done a [TypePad version](http://www.yannicklejeune.com/2008/09/tumulus-wp-cumu.html) based in part on Steve's work. * Christian Philipp's created a [TYPO3 version](http://typo3.org/extensions/repository/view/t3m_cumulus_tagcloud/current/). * Rob Antonishen did a [Serendipity version](http://spartacus.s9y.org/index.php?mode=bygroups_event_en) (search for serendipity\_event\_freetag). * Big Bear maintains the [Joomla version](http://joomlabear.com/Downloads/). * Pratul Kalia and Bj鰎n Jacob have ported it to [Drupal](http://drupal.org/project/cumulus). * Ryan Tomlinson has a [BlogEngine.NET version](http://www.99atoms.com/post/BlogCumulusNET-A-flash-based-tag-cloud.aspx). * I wrote [this post](http://www.roytanck.com/2008/05/19/how-to-repurpose-my-tag-cloud-flash-movie/) on how to use the flash movie in other contexts. == Screenshots == 1. The tag sphere. You can set colors that match your theme on the plugin's options page. 2. The options panel. 3. There's a separate one for the widget. == Options == The options page allows you to change the Flash movie's dimensions, change the text color as well as the background. = Width of the Flash tag cloud = The movie will scale itself to fit inside whatever dimensions you decide to give it. If you make it really small, chances are people will not be able to read less-used tags that are further away. Anything up from 300 will work fine in most cases. = Height of the Flash tag cloud = Ideally, the height should be something like 3/4 of the width. This will make the rotating cloud fit nicely, while the extra width allows for the tags to be displayed without cropping. Western text is horizontal by nature, which is why the ideal aspect is slightly landscape even though the cloud is circular. = Color of the tags = Type the hexadecimal color value you'd like to use for the tags, but not the '#' that usually precedes those in HTML. Black (000000) will obviously work well with light backgrounds, white (ffffff) is recommended for use on dark backgrounds. Optionally, you can use the second input box to specify a different color. When two colors are available, each tag's color will be from a gradient between the two. This allows you to create a multi-colored tag cloud. = Background color = The hex value for the background color you'd like to use. This options has no effect when 'Use transparent mode' is selected. = Use transparent mode = Turn on/off background transparency. Enabling this might cause issues with some (mostly older) browsers. Under Linux, transparency doesn't work in at all due to a known limitation in the Flash player. = Rotation speed = Allows you to change the speed of the sphere. Options between 25 and 500 work best. = Distribute tags evenly on sphere = When enabled, the movie will attempt to distribute the tags evenly over the surface of the sphere. = Display = Choose whether to show tags only, categories only, or both mixed together. Choosing 'both' can result in 'duplicate tags' if you have categories and tags with the same name. These words will appear twice, with one linking to the tag and the other to the category overview. = wp tag cloud parameters = This setting allows you to pass parameters to the wp\_tag\_cloud function, which is used to fetch the tag cloud. Use caution with this setting. Everything you enter will be passed to the function. Be sure to read the function's manual. Please also note that these parameters affect tags only. If you've chosen to show categories or both, the category 'tags' will not be affected. == Version history == = Version 1.16 = + Fixes an issue with categories being rendered black when all of them have the same number of posts. + Reduces the default font size (from the biggest possible to "medium") in that same situation. + Significantly reduces CPU load when the cloud isn't moving. = Version 1.15 = + Adds the possibility to create a multi-colored tag cloud by entering a second tag color. = Version 1.14 = + Fixes an issue where no tags are displayed when viewing the movie locally in MSIE. + Fixes an issue where one random tag would not be displayed. = Version 1.13 = + No longer breaks when the wp-content folder is moved to a non-standard location. = Version 1.12 = + First version hosted on WordPress.org, and released under GPL license. + Uses the Arial font to avoid font licensing issues. = Version 1.11 = + Restores an earlier fix for IE to force loading of the Flash movie. = Version 1.1 = + Complete rewrite of the Flash movie (Actionscript 3, requires Flash Player 9 or better). + Better mouse detection. + Adds option to distribute the tags evenly over the sphere. + Adds support for categories. + Adds the ability to pass parameters to the WordPress wp_tag_cloud function. + Several smaller enhancements. = Version 1.05 = * Fixes several issues with IE, including an issue where it was impossible to use the regular version and the widget on the same page. Thanks to Fadi for alerting me to these. = Version 1.04 = * Fixes the 'it kills my blog' error for people using PHP 5.2 or newer. Thanks to Mujahid for helping me debug this. * Speed improvements in the Flash code. = Version 1.03 = * Removes the wp_head hook in yet another attempt to fix issues with some other plugins and themes. * Reduces system overhead by storing less options. * Adds setting for speed. * Adds a widget with seperate options (size, colors, speeds, etc). * Attemps to detect when the mouse leaves the movie, reducing the 'spinning, but not out of control' effect. * Several minor fixes. = Version 1.02 = * Fixes issues with sites not loading after activation, reduces server load and fixes lost spaces in tags. Thanks to Dimitry for helping me debug these issues. = Version 1.01 = * Fixes an issue where the cloud would spin out of control when the browsers loses focus on OSX. = Version 1.00 = * Initial release version. ------------------------------------------------------------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值