unique_ptr代码练习 配合原子之音自用

unique_ptr代码练习

unique_ptr代码练习

准备:自定义类cat

cat.h声明了构造函数析构函数,成员函数cat_info,set_name, get_name:

//"cat.h"
#include<string>
#include<iostream>
#ifndef CLION_PROJ_CAT_H
#define CLION_PROJ_CAT_H
class cat{
public:
    cat();
    cat(std::string name);
    ~cat();
    void cat_info()const;
    void set_name(const std::string name);
    std::string get_name() const;
private:
    std::string name="miao";
};
#endif //CLION_PROJ_CAT_H

cat.cpp给出函数定义

//"cat.cpp"
#include "cat.h"
#include <iostream>
using namespace std;
cat::cat(){
    cout<<"no params, constructor of cat:"<<name<<endl;
}
cat::cat(std::string name):name(name){
//    this->name=name;
    cout<<"constructor of cat:"<<name<<endl;
}
cat::~cat(){
    cout<<"destructor of cat: "<<name<<endl;
}
void cat::cat_info() const {
    cout<<"cat name: "<<name<<endl;
}
std::string cat::get_name() const{
    return name;
}
void cat::set_name(const std::string name) {
    this->name=name;
}

一、在栈上创建一个cat类型对象

//main.cpp
#include <iostream>
#include <memory>
#include "cat.h"
using namespace std;

int main(){
    //stack:
    cat c1("cat in stack");
    c1.cat_info();
    {
        cat c1("cat in stack inner");
        c1.cat_info();
    }
        cout<<"-----over-----------"<<endl;
    return 0;
}

作用域结束自动调用析构函数

constructor of cat:cat in stack
cat name: cat in stack
constructor of cat:cat in stack inner
cat name: cat in stack inner
destructor of cat: cat in stack inner
-----over-----------
destructor of cat: cat in stack

二、堆上创建裸指针

	//in "main.cpp"
    //heap: raw pointer
    cat* c_p1=new cat("cat by raw_ptr");
    c_p1->cat_info();//cat name: cat by raw_ptr
    int *i_p1=new int(100);
    {
        int* i_p1=new int(200);//这里是声明了一个新的i_p1,与外部的不是同一个
        c_p1=new cat("cat by raw_ptr inner"); //与外部的是同一个
        c_p1->cat_info();//cat name: cat by raw_ptr inner
        delete c_p1;//destructor of cat: cat by raw_ptr inner
        delete i_p1;
    }
    cout<<*i_p1<<endl;  //100,因为200是在局部作用域声明的,
//    delete c_p1; //在局部作用域已经delete 不能再delete
    delete i_p1;

存在的问题

因为作用域的不同,很容易出错或造成内存泄漏

三、unique_ptr的创建方式

1. 通过已有的裸指针

语法
cat* c_p2 = new cat("by_std::unique_ptr");
    std::unique_ptr<cat> u_p1{c_p2};
实例
    //create1: std::unique_ptr通过已有的裸指针初始化
    cat* c_p2 = new cat("by_std::unique_ptr");
    std::unique_ptr<cat> u_p1{c_p2};
    u_p1->cat_info();

    //test: c_p2还能用吗? 可以
    c_p2->set_name("new_name");
    c_p2->cat_info(); //new_name
    u_p1->cat_info(); //new_name, 创建时使用的裸指针可以修改 u_p1指向的对象
    //失去了独占的意义
    // 建议销毁原来的 c_p2:
    c_p2=nullptr;//必须有这一步
    delete c_p2;
    u_p1->set_name("nnew");
    u_p1->cat_info();//nnew
注意事项:

要把原来的裸指针置空然后销毁,不然就失去了独占的意义。

2. new创建

语法
    std::unique_ptr<cat> u_p2 (new cat);//调用无参
    std::unique_ptr<cat> u_p3 (new cat());//调用无参
    std::unique_ptr<cat> u_p4 (new cat("create2"));//调用含参
实例
      //create2: new

  std::unique_ptr<cat> u_p2 (new cat);
  std::unique_ptr<cat> u_p3 (new cat());
  std::unique_ptr<cat> u_p4 (new cat("create2"));
  u_p2->cat_info();//默认的 miao
  u_p2->set_name("oo");
  u_p2->cat_info();//oo

  u_p3->cat_info();//默认的 miao
  u_p3->set_name("mm");
  u_p3->cat_info();//mm

  u_p4->cat_info();//create2
  u_p4->set_name("nn");
  u_p4->cat_info();//nn

3. make_unique 创建

语法
    std::unique_ptr <cat> u_p5= make_unique<cat>();
    //std::unique_ptr <cat> u_p6= make_unique<cat>;  //error
    std::unique_ptr <cat> u_p7= make_unique<cat>("ccc");
实例
    //create3: make_unique
    std::unique_ptr <cat> u_p5= make_unique<cat>();
    //std::unique_ptr <cat> u_p6= make_unique<cat>;  //error
    std::unique_ptr <cat> u_p7= make_unique<cat>("ccc");
    u_p5->cat_info();//miao
    u_p5->set_name("aa");
    u_p5->cat_info();//aa

    u_p7->cat_info();//ccc
    u_p7->set_name("ddd");
    u_p7->cat_info();//ddd

四、get()获取地址与解引用的使用

    //get()获取地址
    std::unique_ptr<int> i_p1 {new int(100)};
    std::unique_ptr<cat> u_p8 {new cat("qaq")};
    cout<<"int address: "<<i_p1.get()<<endl; //int address: 0x256dbfc1b40
    cout<<"cat address: "<<u_p8.get()<<endl; //cat address: 0x256dbfc1b80

    cout<<"deref i_ptr: "<<*i_p1<<endl; //deref i_ptr: 100

    std::unique_ptr<int> i_p2= make_unique<int>(200);
    std::unique_ptr<cat> u_p9= make_unique<cat>("pp");//constructor of cat:pp
    cout<<"int address: "<<i_p2.get()<<endl;//int address: 0x22f46a41b40
    cout<<"cat address: "<<u_p9.get()<<endl;//cat address: 0x22f46a41b80
    cout<<"deref i_ptr: "<<*i_p2<<endl;//deref i_ptr: 200

参考链接: b站原子之音

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值