C++类对象的创建销毁、资源消耗、以及更简单高效的存储方式

c++系列文章目录


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


一、C++几种常用的函数是什么?

C++11六大函数(构造函数,移动构造函数,移动赋值操作符,复制构造函数,赋值操作符,析构函数)。
一、构造函数
二、移动构造函数
三、移动赋值操作符
四、复制构造函数
五、赋值操作符
六、析构函数

class Temp
{
public:
	Temp(const char* str = nullptr);//构造函数
	Temp(Temp&& t);                //移动构造函数               浅拷贝
	Temp& operator = (Temp&& t);   //移动赋值操作符,重载=操作符  浅拷贝
	Temp(const Temp& t);           //复制构造函数    深拷贝
	Temp& operator = (Temp& t);    //复制赋值操作符  深拷贝
	~Temp(void);                   //析构函数
public:
	char* m_pData;
};

 //构造函数
Temp::Temp(const char* str)
{
	if (!str){
		m_pData = nullptr;
	}
	else{
		this->m_pData = new char[1];
		*m_pData=*str;	
	}
	cout<<"构造函数:"<<m_pData<<endl;
}
 //复制构造函数
Temp::Temp(const Temp& t)
{
	if (!t.m_pData){
		this->m_pData = nullptr;
	}
	else{
		this->m_pData = new char[1];  //深复制
		*m_pData=*t.m_pData;
	}
	cout<<"复制构造函数1:"<<m_pData<<endl;
	//cout<<"复制构造函数2:"<<t.m_pData<<endl;
}
 //析构函数
Temp::~Temp(void)
{
	if (this->m_pData){
		delete[] this->m_pData;
		this->m_pData = nullptr;
		//cout<<"delete析构函数"<<endl;
	}
	cout<<"析构函数"<<endl;
}
 //复制赋值操作符
Temp& Temp::operator=(Temp& t)
{
	if (this != &t){
		delete[] this->m_pData;
		if (!t.m_pData){
			this->m_pData = nullptr;
		}
		else{
			this->m_pData = new char[1]; //深复制
			*m_pData=*t.m_pData;
		}
	}
 	cout<<"复制赋值操作符1:"<<m_pData<<endl;
	//cout<<"复制赋值操作符2:"<<t.m_pData<<endl;
	return *this;
}

//移动构造函数
Temp::Temp(Temp&& t)
:m_pData(move(t.m_pData))
{
	t.m_pData = nullptr;
	cout<<"移动构造函数:"<<m_pData<<endl;
}

 //移动赋值操作符,重载=操作符
Temp& Temp::operator=(Temp&& t)
{
	assert(this != &t);  //assert作用是如果它的条件返回错误,则终止程序执行
	this->m_pData = nullptr;
	this->m_pData = move(t.m_pData);
	t.m_pData = nullptr;
	cout<<"移动赋值操作符:"<<this->m_pData<<endl;
	return *this;
 
}

二、优化过程

1.源代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <stdio.h>
#include <unistd.h> 
#include <queue>
#include <deque>
#include <memory>
#include <string.h>


class C
{
public:    
    C(){
        std::cout<< "C构造函数" <<std::endl;
    }
    ~C(){
        std::cout<< "C析构函数" <<std::endl;
    }    
    C(const C& c){
        std::cout<< "C复制构造函数" <<std::endl;
    }
    C(C&& c){
        std::cout<< "C移动构造函数" <<std::endl;
    }
    C& operator = (C& c){
        std::cout<< "C复制赋值操作符" <<std::endl;
    }
    C& operator = (C&& t){
        std::cout<< "C移动赋值操作符" <<std::endl;
    }
private:
};
using CPtr = std::shared_ptr<C>;


class A
{
public:    
    A(){
        std::cout<< "A构造函数" <<std::endl;
        pChar.reset(new char[128]);
        memcpy(pChar.get(),"hello",128);
    }
    ~A(){
        std::cout<< "A析构函数" <<std::endl;
    }    
    A(const A& a){
        std::cout<< "A复制构造函数" <<std::endl;
    }
    A(A&& a){
        std::cout<< "A移动构造函数" <<std::endl;
    }
    A& operator = (A& a){
        std::cout<< "A复制赋值操作符" <<std::endl;
    }
    A& operator = (A&& t){
        std::cout<< "A移动赋值操作符" <<std::endl;
    }
    void print(){
        std::cout<< "string is : "<< pChar.get() <<std::endl;
    }
private:
    C c;
    std::shared_ptr<char> pChar;
};
using APtr = std::shared_ptr<A>;


template<class T>
class BlockingQueue {
public:
    BlockingQueue() : _data(), _mutex(), _condition() {}

    BlockingQueue(const BlockingQueue &) = delete;
    BlockingQueue &operator=(const BlockingQueue &) = delete;

    void push(T &&value) {
        std::unique_lock<std::mutex> lock(_mutex);
        _data.emplace(value);
        _condition.notify_one();
    }

    void push(const T &value) {
        std::unique_lock<std::mutex> lock(_mutex);
        _data.push(value);
        _condition.notify_one();
    }
    size_t size() const {
        std::unique_lock<std::mutex> lock(_mutex);
        return _data.size();
    }   
    void clear(){
        std::unique_lock<std::mutex> lock(_mutex);
        std::queue<T> empty;
        swap(empty, _data);
        _condition.notify_one();         
    }

    bool wait_for(unsigned int timeout, T *pData = nullptr) {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_data.empty()){
            while (_condition.wait_for(lock,std::chrono::seconds(timeout)) == std::cv_status::timeout) { 
                std::cout << '.';                                                                                            
            }                                                             
        }
        if (pData) *pData = std::move(_data.front());
        _data.pop();
        return true;
    }   
private:
    std::queue<T> _data;
    std::mutex _mutex;
    std::condition_variable _condition;    
};

int main()
{    
    BlockingQueue<A> myworlds2;
    {
        std::thread([&](){
            A val;
            myworlds2.wait_for(10,&val);
            //val.print();
        }).detach();

        A a2;
        myworlds2.push(a2);   
    }    
    return 0;
}

发现上面调用,即便我们使用右值等,仍然会多次调用构造、拷贝构造、析构函数等。
在这里插入图片描述

2.源代码

对于大内存、上面的操作不仅仅会让我们绕晕,云里雾里,C++功底不够的时候,建议不要按照上面的方法进行构造类对象,那么我们有个“简单高效的方法”可以解决上面的多次创建与销毁。

1、采用智能指针来传递对象
2、类中定义大对象,建议用智能指针管理
新增方法如下:

    bool wait_for(unsigned int timeout, T &pData) {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_data.empty()){
            while (_condition.wait_for(lock,std::chrono::seconds(timeout)) == std::cv_status::timeout) { 
                    std::cout << '.';                                                                                            
            }                                                             
        }
        pData = _data.front();
        _data.pop();
        return true;
    }  

调用实现代码如下:

BlockingQueue<APtr> myworlds3;
{
    std::thread([&](){
        std::shared_ptr<A> pData;
        myworlds3.wait_for(10,pData);
        //pData->print();
        //std::cout<< "get a A instance" <<std::endl;
    }).detach();
    APtr APtrInst = std::make_shared<A>();
    myworlds3.push(APtrInst);
} 

在这里插入图片描述


总结

本文讲了一种最最最简单的对象之间的传递,可以减少引用与拷贝,另外不需要过度的理解含义,就可以避免问题的出现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c+猿辅导

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值