企业网站推广名词解释,淘宝运营模式,公司网站建设包括哪些东西,找设计师做网站关于placement new
在https://blog.csdn.net/qq_42604176/article/details/111997397中已经介绍了placement new的形式。 它的形式为new()/delete().我们将分配好内存的指针送入括号中#xff0c;就完成了初步的调用了。 其实我们可以定义放任何的东西到()内部。只放一个指针…关于placement new
在https://blog.csdn.net/qq_42604176/article/details/111997397中已经介绍了placement new的形式。 它的形式为new()/delete().我们将分配好内存的指针送入括号中就完成了初步的调用了。 其实我们可以定义放任何的东西到()内部。只放一个指针的版本是的new()是标准库先写好给我们的。 我们可以重载operator new并写出多个版本如
Foo* pf new(300,c)Foo; //注意这里没有传入指针前提是每一个版本的声明都必须由独特的参数列其中第一个参数必须是size_t,这是因为当没有()时进行的是new Foo操作Foo的大小会被传进operator new中作为第一参数Foo的大小是个size_t类型。所以我们写的各种各样的版本也必须遵循这个规则。第二第三参数等等可由自己设计。new()括号中的就是第二第三参数他们可以指定placement arguments 为初值。 下面是实例
class Foo {
public:Foo() {cout Foo::Foo() endl; };Foo(int) {cout Foo::Foo() endl; throw Bad();} //这里故意抛出异常用来测试 placement operator delete//【1】一般的operator new()的重载void* operator new(size_t size) {return malloc(size);}//【2】这个是标准库已提供的placement new()的重载形式void* operator new(size_t size, void* start) {return start;}//【3】这个是我们重载的 placement new void* operator new(size_t size, long extra) {return malloc(size extra);}//【4】这个也是我们重载的 placement newvoid* operator new(size_t size, long extra, char init) {return malloc(size extra);}//【5】这个也是我们重载的不过我们故意写错定义参数的类型void* operator new(long extra, char init) {return malloc(extra);} //很显然这个版本会报错
};关于placement delete
我们也可以重载placement operator delete并对应着placement operator new写出多个对应版本但他们绝对不会被delete调用。 只有当new所调用的ctor抛出异常才会调用这些重载版本的operator delete。 也就是说重载的placement operator delete是用来释放未能成功创建的对象所占的内存。正如我们所知创建一个对象实际上是先申请空间再调用构造函数。空间申请到了但是对象却没构造出来那么理所当然需要将空间释放 对应上面的四种版本的delete
//【1】一般的 operator delete()的重载
void operator delete(void*,size_t)
{cout operator delete(void*,size_t) endl;
}
//【2】对应第二种
void operator delete(void*,void*)
{cout operator delete(void*,void*) endl;
}
//【3】对应第三种
void operator delete(void*,long)
{cout operator delete(void*,long) endl;
}
//【4】对应第四种
void operator delete(void*,long,char)
{cout operator delete(void*,long,char) endl;
}侯捷老师给出了下面的示例运行到第五种。我们可以发现此时的构造函数调用的是第二种构造函数。在之前的定义中我们在这里抛出了异常。 接下俩便是这几条语句的执行结果 如上所示这些new都被重载了。所以才会打印信息。 按照道理在构造函数抛出异常后会调用自己重载的placement delete打印信息。但在这里并没有这是编译器的原因。
关于basic_string重载new()来扩充申请量
basic_string是标准库里面的一个class就是我们使用的字符串。 如下
template...
class basic_string
{
private:struct Rep {...};...void release() {if(--ref 0) delete this;}inline static void* operator new(size_t,size_t);inline static void operator delete(void*);inline static Rep* create(size_t);...
};operator new的具体代码如下
templateclass charT,class traits, class Allocator
inline void* basic_stringcharT,traits,Allocator::Rep::
operator new(size_t s,size_t extra)
{return Allocator::allocate(s extra * sizeof(charT));
}如何使用看这儿 这里我们把第二参数叫做extra。它的作用是当使用者去创建一个字符串如hello,加上结束符一共6个字符。但是它在分配的时候还会分配extra个字符大小的空间。具体原因不做细究。
templateclass charT,class traits,class Allocator
inline basic_stringcharT,traits,Allocator::Rep*
basic_stringcharT,traits,Allocator::Rep::
create(size_t extra)
{extra frob_size(extra 1);Rep *p new(extra)Rep;...return p;
}它的placement delete重载之后则长这样
templateclass charT,class traits,class Allocator
inline void basic_stringcharT,traits,Allocator::Rep::
operator delete(void* ptr)
{Allocator::deallocate(ptr,sizeof(Rep) reinterpret_castRep*(ptr)-res * sizeof(charT));
}