在 C++11 中,可以使用 make_shared 函数来创建共享指针,它是一个模板函数,可以接受任何类型的参数,并返回一个指向该类型对象的共享指针。它可以将控制块和对象一起分配在堆上,从而避免了两次内存分配,并减少了引用计数的内存开销,相对于直接使用 new
或 shared_ptr
的构造函数,make_shared
更为高效。
以下是 make_shared 函数的语法:
std::shared_ptr<T> make_shared< T >( Args&&... args );
其中,T 表示指向的类型,Args 是类型 T 的构造函数所需的参数列表,在调用时需要传递给构造函数。
下面是 make_shared
的使用方式:
例子1:
#include <memory>
#include <iostream>class MyClass {
public:MyClass() {}~MyClass() {}void func() {std::cout << "Hello world!" << std::endl;}
};int main() {std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();ptr->func();return 0;
}
在上面的代码中,我们使用 make_shared
函数来创建一个指向 MyClass
类对象的共享指针。需要注意的是,make_shared
参数必须是完整类型,因此需要提前定义 MyClass
类。接着,我们可以使用箭头运算符 ->
来调用 MyClass
中的成员函数。
例子2:
#include <iostream>
#include <memory>int main() {std::shared_ptr<std::string> ptr = std::make_shared<std::string>("hello world");std::cout << "ptr value: " << *ptr << std::endl;std::cout << "ptr use count: " << ptr.use_count() << std::endl;return 0;
}
运行:
book@ubuntu:~/Desktop/c++_study$ ./share
ptr value: hello world
ptr use count: 1
除了上述基本用法之外,我们还需要注意以下几个细节:
1). make_shared
可以通过参数列表传递参数给对象的构造函数,例如:
std::shared_ptr<int> ptr = std::make_shared<int>(42);
2).
当某个对象不再被任何指针引用时,make_shared
会自动销毁该对象。如果对象同时还有其他资源(如文件或网络连接)需要释放,则需要在析构函数中处理。
3).
如果程序使用了多线程,不能在多个线程中共同访问同一个 shared_ptr
对象,需要使用 std::atomic<std::shared_ptr<T>>
或 std::mutex
等机制来确保线程安全。
4). make_shared
函数可能会使得控制块和对象分配在同一块连续内存上,从而使得共享指针的内存占用更少。但是,如果使用 make_shared
来创建一个较大的对象,可能会增加堆分配的消耗。
总之,make_shared
是 C++11 提供的一种高效、安全的智能指针工厂函数,使用起来方便且实用。