这个例子是在Qt中使用std::make_shared传参数的时候误用发现的。
我将原来的代码简化,模拟了一下:
#include <iostream>
#include <memory>
class Base
{
public:
Base() {
std::cout << "Base Constructor" << std::endl;
}
~Base() {
std::cout << "Base Destructor" << std::endl;
}
};
class Sample : public Base{
public:
Sample(Base *parent = nullptr, int count = 0) : m_parent(parent), m_count(count){
std::cout << "Sample Constructor, m_count:" << m_count << std::endl;
}
~Sample() {
//if (m_parent != nullptr)
// delete m_parent;
std::cout << "~Sample Destrutor" << std::endl;
}
Base *m_parent;
int m_count;
};
int main()
{
{
std::shared_ptr<Sample> sp = std::make_shared<Sample>(new Sample(nullptr, 10)); //错误的写法
std::cout << "sp->m_count:" << sp->m_count << std::endl;
//std::shared_ptr<Sample> sp = std::make_shared<Sample>(nullptr, 10); //正确的写法
}
getchar();
return 0;
}
看看现在的运行结果:
Base Constructor
Sample Constructor, m_count:10
Base Constructor
Sample Constructor, m_count:0
sp->m_count:0
~Sample Destrutor
Base Destructor
Sample构造了两次,一次是传参的,一次是默认参数的,Sample只析构了一次,这就出现了一次内存泄露。
而且最终的sp中的m_count的值确实默认值0。
看看这个构造函数Sample(Base *parent = nullptr, int count = 0)
正确的写法是:
std::shared_ptr<Sample> sp = std::make_shared<Sample>(nullptr, 10);
这样写才能正确传参数。