目的
主要有某天看了一段源码 发现了一个类似于如下代码式子
类名* 变量名a = new (&变量名b) 类名(变量名b);
然后我寻思这样的代码, 好生奇怪啊, 我承认我孤陋寡闻, 感觉C++还仍然有很多我要去学习的, 我见过如下这样的
类名* 变量名a = new 类名(变量名b);
最开始那段表达式说实在话 我几乎没怎么见过。
如下就围绕这式子展开关于构造函数拓展性学习。
拓展
先定义如下类
class TestForFun
{
public:
TestForFun():
m_d(5)
{
qDebug() << __FUNCTION__ << " default" << this;
}
~TestForFun()
{
qDebug() << __FUNCTION__;
}
//复制构造函数(拷贝)
TestForFun(const TestForFun& other)
{
if(&other != this)
{
this->m_d = other.m_d;
qDebug() << " copy ";
}
qDebug() << __FUNCTION__ << " copy " << this;
}
int m_d;
};
void TestFunc(const TestForFun & f)
{
qDebug() << __FUNCTION__ << " d= " << f.m_d;
}
void TestFunc2(const TestForFun f)
{
qDebug() << __FUNCTION__ << " d= " << f.m_d;
}
- 当参数设置引用时, 是不会调用拷贝构造函数的, 减少了临时对象生成开销时间
TestForFun b;
TestFunc(b);
TestFunc2(b);
2. 一般的话我们初始化指针对象 ,如果将另一个已有的去初始化的,此时会调用拷贝构造函数
TestForFun b;
TestForFun* m = new TestForFun();
qDebug() << m;
TestForFun* g = new TestForFun(b);
qDebug() << g;
3. TestForFun* c = new (&b) TestForFun(b); 我们会发现他依然走拷贝构造函数,但是却不走
if(&other != this)
{
this->m_d = other.m_d;
qDebug() << " copy ";
}
现象就是: 它调用拷贝构造函数, 但是又是它本身–地址一样
我寻思它是啥, 网上搜了相关篇博客, 结果发现它是placemen new 定位new表达式,placement new是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本)。
new 分析
深入分析
知乎
TestForFun b;
TestForFun* c = new (&b) TestForFun(b);
qDebug() << c;
首先我们看下如下代码
class MyClass {…};
MyClass * p=new MyClass;
这里的new实际上是执行如下3个过程:
1.调用operator new分配内存;
2.在分配的内存上调用构造函数生成类对象;
3.返回相应指针。
placement new原型
void *operator new( size_t, void *p ) throw() { return p; }
placement new允许你在一个已经分配好的内存中(栈或堆中)构造一个新的对象。原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。