在 STL 源码剖析 里的奇怪写法,请叫下怎么理解?
#include <new.h>
template <class T1, class T2>
inline void construct(T1* p,const T2& value)
{
new(p) T1(value);//怎么理解?
}
#include <iostream>
using namespace std;
int main()
{
int *p=new int();
int value = 9;
construct(p, value);
cout < <*p < <endl;
}
[解决办法]
在指定内存处构造一个对象.
new(p) T1(value);//在p指向的内存处用value构造一个T1对象. 更多请搜索 "定位new "
[解决办法]
new(p) T1(value) 在地址p处new一个对象出来,一般在实际中不容易遇到,术语叫定位new
[解决办法]
new(p) T1(value
在p指向的内存处用value构造一个T1对象. 更多请搜索 "定位new "
[解决办法]
"new(p) T1(value); "是所谓的 "Placement Operator new ",意即内存(对已分配过的内存块)从新配置。有朋友解释得可以: "new(p) T1(value) 在地址p处new一个对象出来,一般在实际中不容易遇到,术语叫定位new ",其后的 "T1(vlaue) ",也就是显示调用T1的构造函数。
我认为这是一个重要的运算子,特别是在内存资源使用受限的情况下,它将赋予程序
员以丰富的想象空间。
[解决办法]
定位放置new(placement new)有很多作用。最简单的用处就是将对象放置在内存中的特殊位置。这是依靠 new表达式部分的指针参数的位置来完成的:
#include <new> // 必须 #include 这个,才能使用 "placement new "
#include "Fred.h " // class Fred 的声明
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (详见以下的“危险”)
// The pointers f and place will be equal
// ...
}
Line #1 在内存中创建了一个sizeof(Fred)字节大小的数组,足够放下 Fred 对象。Line #2 创建了一个指向这块内存的首字节的place指针(有经验的 C 程序员会注意到这一步是多余的,这儿只是为了使代码更明显)。Line #3 本质上只是调用了构造函数 Fred::Fred()。Fred构造函数中的this指针将等于place。因此返回的 f 将等于place。
建议:万不得已时才使用“placement new”语法。只有当你真的在意对象在内存中的特定位置时才使用它。例如,你的硬件有一个内存映象的 I/O计时器设备,并且你想放置一个Clock对象在那个内存位置。
危险:你要独自承担这样的责任,传递给“placement new”操作符的指针所指向的内存区域必须足够大,并且可能需要为所创建的对象进行边界调整。编译器和运行时系统都不会进行任何的尝试来检查你做的是否正确。如果 Fred 类需要将边界调整为4字节,而你提供的位置没有进行边界调整的话,你就会亲手制造一个严重的灾难(如果你不明白“边界调整”的意思,那么就不要使用placement new语法)。
你还有析构放置的对象的责任。这通过显式调用析构函数来完成:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
// ...
f-> ~Fred(); // 显式调用定位放置的对象的析构函数
}
这是显式调用析构函数的唯一时机。
[解决办法]
这个东西一般没有什么用处.顶多是用来调用一下构造函数.
不过俺一般是用它来做对象变身的.....^_^
比如:
#include <iostream>
class base{
public:
virtual void foo() = 0;
virtual void transform() = 0;
virtual ~base() {}
};
class A : public base{
public:
void foo() {
std::cout < < "class a " < < std::endl;
};
void transform();
};
class B : public base {
public:
void foo() {
std::cout < < "class b " < < std::endl;
};
void transform();
};
void A::transform() {
this-> ~A();
new(this) B();
}
void B::transform() {
this-> ~B();
new(this) A();
}
int main() {
A *a = new A;
a-> foo();
a-> transform();
a-> foo();
a-> transform();
a-> foo();
delete a;
return 0;
}
[解决办法]
那这有什么好处,为什么不会有内存泄露问题?
那这 "定位new "有什么好处?在什么情况下使用?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
关于placement new使用来说,是相当广泛的.
如果想加速内存分配速度,一般都考虑使用placement new机制
比如常见的内存池功能,
placement new的好处就是,当别人给你一段空间的时候,你可以把对象放到
此空间内(这个功能在写硬件驱动时常常用到,主要也是因为这个原因才加入的
placement new机制,参考BJ <c++设计与演化> ),另一个方面,可以在指定的空间
内放置自己的对象,一般情况下,我们是无法决定创建对象的内存地址的,而使用
placement new,我们可以指定创建在指定位置内存空间上.(前提这块内存有效
,并且可用).
如同new与delete一样,placement new与placement delete也必须对应.
不过确切来讲是没有placement delete这个概念的,只是在delete对象时
只调用对象的析构函数,而无需调用operator delete操作
[解决办法]
template <class T1, class T2>
inline void construct(T1* p,const T2& value)
{
new(p) T1(value);
}
楼主啊,认真瞧瞧你的代码,你是在char里放了int么?你是在char里放了(char)x;