C++my_auto_ptr类

本文介绍了如何自定义实现C++中的智能指针auto_ptr,包括自动释放内存、调用对象成员函数及泛型版本的实现。通过具体代码示例展示了自定义auto_ptr的功能,并解释了其工作原理。

my_auto_ptr通过它的析构函数来调用delete删除某对象的指针,来达到自动释放内存,而不需要显示的调用delete某对象。

(1)实现自动释放

#include <iostream>
#include <string>

using namespace std;

struct People 
{
public:
    People() {cout << "People" << endl;}
    ~People() {cout << "~People" << endl;}
    void run(void) const {cout << "Peple can run!" << endl;}
};

class my_auto_ptr
{
public:
    my_auto_ptr(People* p) : p(p) {}
    ~my_auto_ptr() {delete p;}
private:
    People* p;
};

int main(int argc, char *argv[])
{
    my_auto_ptr ptr(new People);

    return 0;
}

程序输出:

People

~People

(2)实现调用该对象的成员

#include <iostream>
#include <string>

using namespace std;

struct People 
{
public:
    People() {cout << "People" << endl;}
    ~People() {cout << "~People" << endl;}
    void run(void) const {cout << "Peple can run!" << endl;}
};

class my_auto_ptr
{
public:
    my_auto_ptr(People* p) : p(p) {}
    ~my_auto_ptr() {delete p;}
    People* operator->() const {cout << "->" << endl; return p;}
    const People& operator*() const {cout << "*" << endl; return *p;}
    const People* operator&() const {cout << "&" << endl; return p;}
private:
    People* p;
};

int main(int argc, char *argv[])
{
    my_auto_ptr ptr(new People);
    
    ptr->run();
    (*ptr).run();
    &ptr;

    return 0;
}

/*
总结:

ptr->run();
这里ptr是一个my_auto_ptr对象,p->run的含义与(p.operator->())->run求值相同。
p.operator->()返回对People对象的指针,然后对返回的People调用run()函数。
*/

程序输出:

 People
->
Peple can run!
*
Peple can run!
&
~People

(3)实现泛型版本

 

#include <iostream>
#include <string>

using namespace std;

struct People 
{
public:
    People() {cout << "People" << endl;}
    ~People() {cout << "~People" << endl;}
    void run(void) const {cout << "Peple can run!" << endl;}
};

class Student {};

template<typename T>
class my_auto_ptr
{
public:
    my_auto_ptr(T* p) : p(p) {}
    ~my_auto_ptr() {delete p;}
    T* operator->() const {cout << "->" << endl; return p;}
    const T& operator*() const {cout << "*" << endl; return *p;}
private:
    T* p;
};

int main(int argc, char *argv[])
{
    my_auto_ptr<People> ptr1(new People);
    my_auto_ptr<Student> ptr2(new Student);

    return 0;
}

 

转载于:https://www.cnblogs.com/Robotke1/archive/2013/05/06/3063103.html

<think> 首先,用户主要询问C++中make_shared和make_unique的语法。用户提到“make_shared和make_unique(原表述可能有误,推测为make_unique)”,这里用户可能指的是make_unique,因为在之前的引用中提到了make_unique。 回顾系统指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 根据示例结构: - 回答应该结构清晰,逐步帮助用户解决问题。 - 使用中文。 - 结尾生成相关问题。 用户的查询是基于站内引用: - 引用[1]讨论了make_unique的实现,适用于C++11。 - 引用[2]展示了智能指针的使用,包括make_unique和make_shared。 关键点: - make_unique从C++14开始引入标准库,但可以在C++11中手动实现。 - make_shared从C++11开始可用。 - 语法:两者都用于创建智能指针对象,以避免直接使用new操作符,从而减少内存泄漏风险。 我的回答结构: 1. **介绍make_shared和make_unique**:简述它们的作用和区别。 2. **语法细节**: - 对于make_shared:语法是`std::make_shared<T>(args...)`,其中T是型,args是构造参数。 - 对于make_unique:语法似,`std::make_unique<T>(args...)`,但需注意C++14标准。 3. **代码示例**:提供示例代码来展示用法。 4. **注意事项**:包括C++版本兼容性,如make_unique在C++11中的实现。 5. **引用标识**:自然地添加引用标识到相关段落。 6. **生成相关问题**:在结尾添加相关问题。 确保LaTeX格式: - 行内数学表达式:变量如`T`、`args`等,需用$...$包裹,例如`$T$`。 - 独立公式:如果有公式,单独成段并用$$...$$,但这里可能不需要,主要是代码块。 代码块: - 在回答中插入代码示例时,使用代码块格式,如示例中的Python代码。 - 语法正确。 相关问题生成: - 基于主题生成2-3个相关问题。 - 例如:性能差异、使用场景、与new操作符的比较等。 完整回答大纲: 1. 开头:解释make_shared和make_unique的作用。 2. 语法部分: - make_shared语法和示例。 - make_unique语法和示例,提及C++11实现。 3. 引用:引用[2]用于智能指针概述,引用[1]用于make_unique实现。 4. 结尾:生成相关问题。 最终输出格式: - 回答主体。 - 相关问题部分以“§§相关问题§§”开头。 </think> ### C++中make_shared和make_unique的语法详解 在C++中,`std::make_shared` 和 `std::make_unique` 是用于创建智能指针的工厂函数,它们通过简化内存管理来避免手动 `delete` 操作,从而减少内存泄漏和双重释放风险。下面我将逐步解释它们的语法、用法和注意事项,并以代码示例演示。参考引用内容中提到的智能指针原理和实现[^2],我将确保语法细节准确可靠。 #### 1. **作用与区别** - **`std::make_shared`**: 从C++11开始引入,用于创建 `std::shared_ptr<T>` 共享指针。它一次性分配内存来存储对象和控制块(引用计数),优化了性能和内存使用。 - **`std::make_unique`**: 从C++14开始引入,用于创建 `std::unique_ptr<T>` 独占指针。在C++11中可通过自定义实现(如引用[1]所示)达到似效果[^1]。 - 核心优势:两者都支持完美转发构造参数,避免直接使用 `new`,提高代码安全性和可读性。 #### 2. **语法格式** - **通用语法模板**: - 函数签名:`std::make_xxx<T>(Args&&... args)` - `$T$`: 要创建的对象型(如 `int`、`MyClass`)。 - `$Args$`: 可变参数模板,匹配对象构造函数的参数。 - 返回值:智能指针(`std::shared_ptr<T>` 或 `std::unique_ptr<T>`)。 - 示例表达式:`auto ptr = std::make_xxx<T>(arg1, arg2, ...);` - **`std::make_shared` 详细语法 (C++11及以上)**: ```cpp #include <memory> std::shared_ptr<T> ptr = std::make_shared<T>(构造参数...); ``` - 说明: - `$T$` 必须是完整型。 - 构造参数通过完美转发传递给 `$T$` 的构造函数。 - 适用于共享所有权场景,多个指针可共享同一对象。 - **`std::make_unique` 详细语法 (C++14及以上)**: ```cpp #include <memory> std::unique_ptr<T> ptr = std::make_unique<T>(构造参数...); ``` - 说明: - `$T$` 可以是基础型、或数组(如 `int[]`)。 - 构造参数同样完美转发。 - 适用于独占所有权,对象生命周期绑定到指针作用域。 - **C++11兼容实现**:如引用[1]所示,可自定义 `my_make_unique` 函数[^1]: ```cpp template <class T, class... Args> std::unique_ptr<T> my_make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } ``` #### 3. **代码示例** 以下示例演示语法用法,基于引用[2]中的智能指针原理[^2]。 - **使用 `std::make_shared` (C++11)**: ```cpp #include <memory> #include <string> class MyClass { public: MyClass(int num, std::string str) : num_(num), str_(str) {} private: int num_; std::string str_; }; int main() { // 创建 shared_ptr,传递构造参数 auto sptr = std::make_shared<MyClass>(42, "Hello"); // 自动管理内存,无需手动 delete } // 离开作用域时内存自动释放 ``` - **使用 `std::make_unique` (C++14)**: ```cpp #include <memory> #include <vector> int main() { // 创建 unique_ptr 管理对象 auto uptr = std::make_unique<std::vector<int>>(10); // 初始化 vector 大小为 10 uptr->push_back(42); // 创建 unique_ptr 管理数组 auto arr_ptr = std::make_unique<int[]>(5); // 数组大小为 5 arr_ptr[0] = 1; // 像普通数组一样访问 } // 内存自动释放 ``` - **C++11 中自定义 `make_unique` (参考引用[1])[^1]**: ```cpp template <class T, class... Args> std::unique_ptr<T> my_make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } int main() { auto ptr = my_make_unique<int>(100); // 等同于 make_unique } ``` #### 4. **注意事项** - **版本兼容性**: - `make_shared`: C++11 及以上直接支持。 - `make_unique`: C++14 及以上原生支持;C++11 需手动实现(如上述 `my_make_unique`)[^1]。 - **性能与内存**: - `make_shared` 合并对象和控制块内存分配,减少开销,但可能延长对象生命周期。 - `make_unique` 无额外控制块,更轻量。 - **错误处理**: 如果构造失败,会抛出异常(如 `std::bad_alloc`),确保资源安全。 - **数组支持**: `make_unique` 直接支持数组(如 `std::make_unique<int[]>(size)`),而 `make_shared` 不支持数组,需自定义删除器。 通过以上语法和示例,您可安全高效地使用智能指针。如需进一步优化(如自定义删除器),可参考RAII原则[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值