结构体new重载有关问题
结构体new重载问题
typedef struct tagMemoryBlock
{
unsigned int uiSize;
unsigned short usFree;
unsigned short usFirst;
tagMemoryBlock *pNext;
char aData[1];
static void* operator new(unsigned int, unsigned short usNum, unsigned short usUnitSize)//为什么第一个参数只有声明了类型而没有实际的参数???
{
return ::operator new(sizeof(tagMemoryBlock) + (usNum * usUnitSize));
}
static void operator delete(void* p, unsigned int)
{
::operator delete(p);
}
tagMemoryBlock(unsigned short usNum, unsigned short usUnitSize)
{
uiSize = (unsigned int)(usNum * usUnitSize);
usFree = usNum;
usFirst = 0;
pNext = 0;
char *pData = aData;
for (int i = 1; i < usNum; ++ i)
{
*((unsigned short *)pData) = i;
pData += usUnitSize;
}
}
~tagMemoryBlock()
{
}
}MemoryBlock, *PMemoryBlock;
pMemoryBlock = new (m_uiGrowNum, m_uiUnitSize) MemoryBlock(m_uiGrowNum, m_uiUnitSize);//这个new 的格式不明白,MemoryBlock(m_uiGrowNum, m_uiUnitSize);这个是结构体的构造函数,这应该是对前面new的结构体初始化,但是new后面只有两个参数,而结构体中的new声明的是3个参数。这个有点不明白,请各位不吝赐教!
------解决方案--------------------
第一个参数是默认传递的。
------解决方案--------------------
重载 operator new
opeator new 的重载和其它操作符大不相同.即使你不重载, 默认的 operator new 也可施用于你的自定义型别上(operator, 也具有此特性), 而其它操作符如果不进行重载就无法使用. 其次, 其它重载其它操作符时参数个数都是固定的, 而 operator new 的参数个数是可以任意的, 只需要保证第一个参数为 size_t, 返回类型为 void * 即可, 而且其重载的参数类型也不必包含自定义类型. 更一般的说, operator new 的重载更像是一个函数的重载, 而不是一个操作符的重载.
------解决方案--------------------
作为c++标准控,我用c++标准回答你。
1. new的语法
我们最常见的就是 new Type; 其中Type可以是int, double或者用户自定义类型。
new也可以这样用(这种用法叫做placement new),
new (expression-list) Type;
其中expression-list就是一个逗号分开的表达式,例如 new (a, b, c) Type。有什么特殊意义呢?
见下面的例子:
— new T 会调用函数 operator new(sizeof(T)),
— new(2,f) T 会调用函数 operator new(sizeof(T),2,f)
sizeof(T)是T的大小,永远作为operator new的第一个参数。标准原文:A new-expression passes the amount of space requested to the allocation function as the first argument of
type std::size_t. That argument shall be no less than the size of the object being created;
实际上就是把(2,f)放到operator new 第二个参数往后推。
为什么这样做呢?因为operator new是一个函数,而我们却不用普通的方法调用该函数,为了能够传递更多的参数,就想出了这么个不伦不类的语法。那你说为什么不这样呢?
new T(2,f)
答案很明显,因为这样(2,f)会被当成T的constructor的参数。
其实new的全写是: new (expression-list)_optional Type (constructor arguments)_optional
_optional是可有可无的意思。
2. 你的问题:
static void* operator new(unsigned int, unsigned short usNum, unsigned short usUnitSize)//为什么第一个参数只有声明了类型而没有实际的参数???
{
return ::operator new(sizeof(tagMemoryBlock) + (usNum * usUnitSize));
}
第一个unsigned int其实应该是std::size_t。编译器会传递该类型的大小(sizeof(tagMemoryBlock))。
但是很明显该函数的实现忽略了该大小,而是直接用了sizeof(tagMemoryBlock)。其实他也可以直接利用第一个参数而不用sizeof().
pMemoryBlock = new (m_uiGrowNum, m_uiUnitSize) MemoryBlock(m_uiGrowNum, m_uiUnitSize);
就相当于调用 operator new(sizeof(tagMemoryBlock), m_uiGrowNum, m_uiUnitSize)
然后再调用constructor tagMemoryBlock(m_uiGrowNum, m_uiUnitSize)
------解决方案--------------------
“//为什么第一个参数只有声明了类型而没有实际的参数???”
这个是标准规定必须有第一个这样的参数;
另外,3楼说的很好。
pMemoryBlock = new (m_uiGrowNum, m_uiUnitSize) MemoryBlock(m_uiGrowNum, m_uiUnitSize);
中"new (m_uiGrowNum, m_uiUnitSize)"表示按照你自定义的new申请内存方式申请了内存;
后面的"MemoryBlock(m_uiGrowNum, m_uiUnitSize)"表示在刚刚申请的内存上构造这个对象。
具体new的用法,可参考下面的这个地址,讲的很好:
http://www.360doc.com/content/10/0416/15/1066294_23344701.shtml
------解决方案--------------------
typedef struct tagMemoryBlock
{
unsigned int uiSize;
unsigned short usFree;
unsigned short usFirst;
tagMemoryBlock *pNext;
char aData[1];
static void* operator new(unsigned int, unsigned short usNum, unsigned short usUnitSize)//为什么第一个参数只有声明了类型而没有实际的参数???
{
return ::operator new(sizeof(tagMemoryBlock) + (usNum * usUnitSize));
}
static void operator delete(void* p, unsigned int)
{
::operator delete(p);
}
tagMemoryBlock(unsigned short usNum, unsigned short usUnitSize)
{
uiSize = (unsigned int)(usNum * usUnitSize);
usFree = usNum;
usFirst = 0;
pNext = 0;
char *pData = aData;
for (int i = 1; i < usNum; ++ i)
{
*((unsigned short *)pData) = i;
pData += usUnitSize;
}
}
~tagMemoryBlock()
{
}
}MemoryBlock, *PMemoryBlock;
pMemoryBlock = new (m_uiGrowNum, m_uiUnitSize) MemoryBlock(m_uiGrowNum, m_uiUnitSize);//这个new 的格式不明白,MemoryBlock(m_uiGrowNum, m_uiUnitSize);这个是结构体的构造函数,这应该是对前面new的结构体初始化,但是new后面只有两个参数,而结构体中的new声明的是3个参数。这个有点不明白,请各位不吝赐教!
------解决方案--------------------
第一个参数是默认传递的。
------解决方案--------------------
重载 operator new
opeator new 的重载和其它操作符大不相同.即使你不重载, 默认的 operator new 也可施用于你的自定义型别上(operator, 也具有此特性), 而其它操作符如果不进行重载就无法使用. 其次, 其它重载其它操作符时参数个数都是固定的, 而 operator new 的参数个数是可以任意的, 只需要保证第一个参数为 size_t, 返回类型为 void * 即可, 而且其重载的参数类型也不必包含自定义类型. 更一般的说, operator new 的重载更像是一个函数的重载, 而不是一个操作符的重载.
------解决方案--------------------
作为c++标准控,我用c++标准回答你。
1. new的语法
我们最常见的就是 new Type; 其中Type可以是int, double或者用户自定义类型。
new也可以这样用(这种用法叫做placement new),
new (expression-list) Type;
其中expression-list就是一个逗号分开的表达式,例如 new (a, b, c) Type。有什么特殊意义呢?
见下面的例子:
— new T 会调用函数 operator new(sizeof(T)),
— new(2,f) T 会调用函数 operator new(sizeof(T),2,f)
sizeof(T)是T的大小,永远作为operator new的第一个参数。标准原文:A new-expression passes the amount of space requested to the allocation function as the first argument of
type std::size_t. That argument shall be no less than the size of the object being created;
实际上就是把(2,f)放到operator new 第二个参数往后推。
为什么这样做呢?因为operator new是一个函数,而我们却不用普通的方法调用该函数,为了能够传递更多的参数,就想出了这么个不伦不类的语法。那你说为什么不这样呢?
new T(2,f)
答案很明显,因为这样(2,f)会被当成T的constructor的参数。
其实new的全写是: new (expression-list)_optional Type (constructor arguments)_optional
_optional是可有可无的意思。
2. 你的问题:
static void* operator new(unsigned int, unsigned short usNum, unsigned short usUnitSize)//为什么第一个参数只有声明了类型而没有实际的参数???
{
return ::operator new(sizeof(tagMemoryBlock) + (usNum * usUnitSize));
}
第一个unsigned int其实应该是std::size_t。编译器会传递该类型的大小(sizeof(tagMemoryBlock))。
但是很明显该函数的实现忽略了该大小,而是直接用了sizeof(tagMemoryBlock)。其实他也可以直接利用第一个参数而不用sizeof().
pMemoryBlock = new (m_uiGrowNum, m_uiUnitSize) MemoryBlock(m_uiGrowNum, m_uiUnitSize);
就相当于调用 operator new(sizeof(tagMemoryBlock), m_uiGrowNum, m_uiUnitSize)
然后再调用constructor tagMemoryBlock(m_uiGrowNum, m_uiUnitSize)
------解决方案--------------------
“//为什么第一个参数只有声明了类型而没有实际的参数???”
这个是标准规定必须有第一个这样的参数;
另外,3楼说的很好。
pMemoryBlock = new (m_uiGrowNum, m_uiUnitSize) MemoryBlock(m_uiGrowNum, m_uiUnitSize);
中"new (m_uiGrowNum, m_uiUnitSize)"表示按照你自定义的new申请内存方式申请了内存;
后面的"MemoryBlock(m_uiGrowNum, m_uiUnitSize)"表示在刚刚申请的内存上构造这个对象。
具体new的用法,可参考下面的这个地址,讲的很好:
http://www.360doc.com/content/10/0416/15/1066294_23344701.shtml
------解决方案--------------------