The company does not let the piracy, prepare each software either replace it into open source, or write, look at it, it is the simplest number of ACDSEE (some advanced features are all used), line, start from this.
Demand Analysis: Basic image viewing features, image format conversion feature, basic graphical transformation function.
Technical feasibility analysis: GDI provided by MS
It has provided a professional graphic display, format conversion function, and is easy to use.
....
OK, ready, start dry.
However, in the process of programming, there is an error message makes me very unconfil. There is a statement in the program:
BMPHOTO
=
New bitmap
(Thumbnail_width
Thumbnail_height
Pixelformat24bpprgb
);
Each time debug is compiled, the following error is reported:
Error C2660
:
'new'
: Function Does
NOT TAKE
3 parameters
Start thinking is a problem with the building function of Bitmap, but check it, Bitmap is clearly constructed:
Bitmap
(In int width
,
In int Height
,
In Pixelformat Format
= Pixelformat32bppargb
);
What is the problem? The Internet discussed, and finally lock the problem in such a macro in the MFC program:
#ifdef _debug # define new debug_new # undef this_file
Static
Char this_file
[] = __File__
;
#ENDIF These lines never caused what problems with the code we pay attention to?
• Why make our code report to compile errors as described above?
?
Let's take a look at Debug_New definition (in AFX)
in .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 See here you might think,
New was become Debug_new by Define, and the latter was become Define.
New
(...), this is not a cycle
? Due to AFX
.H earlier than any other header file is included
(stdafx
.h contains AFXWIN
Hh, AFXWIN
.h contains AFX
.h, and MFC requires us to include STDAFX before any valid code
.h, of course, this is not necessary
), So Debug_new defines the next #define behind it.
New debug_new, that is, this Define is only valid for the rear code, and the AFX that has been included in front.
The code in .h is invalid.
Only the topic is now, now returns to the topic.
MFC overload
Operator new, is to facilitate positioning memory leaks, after heavy load
The Operator New will record __file__ and __line__ information corresponding to each block allocated. Generally speaking, the standard Operator New declaration is as follows:
Void
* __ cdecl
Operator new
(SIZE_T
);
That is, it has only one parameter, only receives a size information. Our following code
int
* Pi
=
New
int
;
// The Same as int * pi = new int (); or int * pi = new int [1]; equivalent
int
* TPI
=
int
*)
Operator new
(
Sizeof
(
int
));
// attention: this line cannot pass compi1 you have define debug_new
int
* Pi
= TPI
;
Similarly, definition Debug_new, this statement begins with error:
Bitmap
* BMPHOTO
=
New bitmap
(Thumbnail_width
Thumbnail_height
Pixelformat24bpprgb
);
Equivalent to
Bitmap
* TBMPHOTO
Bitmap
*)
Operator new
(
Sizeof
(Bitmap
));
TBMPHOTO
-> Bitmap
(Thumbnail_width
Thumbnail_height
Pixelformat24bpprgb
);
// Initialize VariableBitmap
* BMPHOTO
= TBMPHOTO
;
But now, since Debug_New uses it is overloaded
Operator new:
Void
* AFX_CDECL
Operator new
(SIZE_T NSIZE
, LPCSTR LPSZFILENAME
,
Int nline
);
The above code is equivalent to:
Bitmap
* TBMPHOTO
Bitmap
*)
Operator new
(
Sizeof
(Bitmap
), __File__
, __LINE__
);
TBMPHOTO
-> BitmapBitmap
(Thumbnail_width
Thumbnail_height
Pixelformat24bpprgb
);
// Initialize VariableBitmap
* BMPHOTO
= TBMPHOTO
;
Go back and see GDIPLUS
in
Operator new declaration (in Gdiplusbase
in .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);}};
It is overloaded
Operator new, and no one can accommodate
3 parameters
Operator New, at the same time, based on the fact:
Different nomencartments (referring to overloading between global namespaces, parent class, subclasses, global and classes), the next level of namespace covers the definition of the previous level unless the call is called The definition of the last level.
Therefore, the overall redefined
Operator New cannot be used for Bitmap classes. Also because of this reason, the compiler will report:
Bitmap
* TBMPHOTO
Bitmap
*) Bitmap
::
Operator new
(
Sizeof
(Bitmap
), __File__
, __LINE__
);
Error C2660
:
'new'
: Function Does
NOT TAKE
3 parameters
I know this, I have to fix this problem, just give
Class Gdiplusbase multiple loads more
Operator new. Corrected
Class gdiplusbase is as follows:
#ifdef _Debug
Namespace gdiplus
{
Namespace Dllexports
{
#include
}
#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
}};
#ndif // #ifndef _GdiplusBase_H
}
#ndif // #ifDef _debugok, the problem has been resolved, in fact this is just a heavy load
Operator new problem, but this problem has become a bit complicated because of Debug_new.
Finally, summarize it,
Operator new overload should be taken:
1.
New operator is not overloaded, it can be overloaded
Operator new.
New Operator first call
Operator New, then call the constructor (if any).
This behavior of New Operator is not overloaded, it can be overloaded is only
Operator New, that is, memory allocation.
2. Overload
Operator New is a very careful thing, and overloaded the MFC program or the system you have written.
When Operator New, you should pay attention to it, and you should pay attention to all the #include header files to be added before all Define, so as not to cause subsequent pairs.
The impact of NEW's redefinition. You can try #define in your MFC program
After new debug_new, add #include
>, You will receive a lot of inexplicable wonderful error tips (Debug compiles), this is because #define New debug_new and behind Static Char this_file [] = __File__ Caused by the impact. 3. Operator new / Delete is similar to a static function in nature, you can access them directly through class names. 4. Understand Operator New's basic concept, you must understand the Placement in the header file NEW New / DELETE is not a difficult thing, the toppers in the header file NEW New / DELETE is achieved as follows: #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 Attachment: (Reposted ) C NEW Introduction 1. New T The first New simplest Calling class If overloaded ) Or global Operator new allocation space , Then call the constructor with the parameters of the column column after the type Usage New TypeName (Initial_Args_List ). If there is no parameters , Parentheses can generally omit .E.g int * P = New int ; int * P = New int ( 10 ); int * P = New foo ( "hello" ); Call Delete is destroyed : Delete P ; 2. New T [] This New used to create a dynamic object array He will call the object Operator new [] To allocate memory (If you don't call Operator new , Search order ), Then call the 31M default constructor of the object to initialize each object usage : New TypeName Num_of_Objects ]; E.g int * P = New int [ 10 ]; Use when destroy Operator delete31m [] 3. New () T and New () T [] This is a parameter New , This form NEW will call Operator new (SIZE_T Othertype ) To allocate memory Here, Othertype is compatible with the type of parameters in New Braces. This syntax is usually used in a particular address component object. Placement, called Placement New Prerequisite Operator new (SIZE_T , Void *) Has been defined Usually the compiler has provided an implementation ,contain < New > Head file This implementation is simply returned to the specified address of the parameters. ,thus New () Operators will create objects on the address in parentheses . It should be noted The second parameter is not necessarily Void *, Legitimate types that can be identified , At this time overload mechanism to determine the call Operator new . of course We can provide yourself Operator new (SIZE_ ,Ys ) NEW behavior ,such as Char Data [ 1000 ] [ Sizeof (foo )]; inline Void * Operator new (SIZE_T , Int n ) { Return Data [N } You can use such interesting syntax to create an object : foo * P = New ( 6 ) Foo (); // Index to the Sixth Unit of the object in the sixth unit of DATA is really interesting in the standard library also provides a NothRow implementation : Void * Operator new (STD :: SIZE_T , Const STD :: Nothrow_t &) Throw (); Void * Operator new [] (STD :: SIZE_T , Const STD :: Nothrow_t &) Throw (); Call can be called Does not throw an exception when the New fails New (nothrow ) int ( 10 ); // Nothrow is an instance of std :: nothrow_t Placement NEW created objects cannot be directly Delete is destroyed Instead, to call the paid function of the object to destroy the object How to deal with the memory occupied by the object To see the specific source of this memory . 4. Operator new (SIZE_T ) This operator assigns parameters Specify the size of the memory and returns the first address. , Can overload this operator for custom class The method is to declare in the class Void * Operator new (SIZE_T SIZE ) { / / Allocate memory here and return its address } No matter whether it is declared Various Operator New and Operator delete has Static property . Never need to call directly Operator new Unless the original memory is directly assigned (This is similar to the malloc of C ), In the conflict, call the global Operator plus :: Scope Operator ::: Operator new ( 1000 ); // Allocate 1000 31M bytes Returned memory needs to be recycled Call corresponding Operator delete 5. Operator new [] (SIZE_T ) This is also allocated memory ,, Only is specifically for arrays That is New T This form ,of course , Can be explicitly called when needed 6. Operator new (SIZE_T SIZE , Othertype Other_Value ) with Operator new [] (SIZE_T SIZE , Othertype Other_Value ) See New () Need to emphasize , NEW is used to create objects and allocate memory It is not changeable It can be changed. Operator new We can overload Operator New to implement our memory allocation scheme . Reference: 1.prb : Microsoft Foundation Classes Debug_new Does Not Work with GDI . Http : //support.microsoft.com/default.aspx?scid=kb;n-us; 317799 2.vc 6.0 memory leak detection 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 .