欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++深淺拷貝和寫時拷貝圖文詳解

 更新時間:2021年04月08日 11:51:24   作者:_Camille  
這篇文章主要給大家介紹了關(guān)于C++深淺拷貝和寫時拷貝的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

之前我們在淺談6個成員函數(shù)中有提到深淺拷貝的問題,現(xiàn)在再回首掏一把。

一、深淺拷貝哪家強?

先給出代碼理一理

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include<assert.h>
using namespace std;

class String
{
	friend ostream& operator<<(ostream &out, const String &s);
public:
	String(const char* str = "")
	{
		m_data = new char[strlen(str) + 1];
		strcpy(m_data, str);
	}
	//String(const String& s)//qian拷貝
	//{
	//	m_data = s.m_data;
	//}
	String(const String& s)//深拷貝
	{
		m_data = new char[strlen(s.m_data) + 1];
		strcpy(m_data, s.m_data);
	}
	String& operator=(const String& s)
	{
		if (this != &s)
		{
			delete[]m_data;
			m_data = new char[strlen(s.m_data) + 1];
			strcpy(m_data, s.m_data);
		}
		return *this;
	}
	~String()
	{
		delete[]m_data;
		m_data = nullptr;
	}
private:
	char* m_data;
};

ostream& operator<<(ostream &out, const String &s)
{
	out << s.m_data;
	return out;
}

void main()
{
	String s1("abc");
	String s2 = s1;
	cout << "s1 = " << s1 << endl;
	cout << "s2 = " << s2 << endl;
}

而我們之前所說的淺拷貝崩潰是因為doublefree的問題,因此我們可以定義一個引用計數(shù)器,來記錄當前使用該值的對象數(shù),如果數(shù)目大于1,則不釋放內(nèi)存。

class String
{
	friend ostream& operator<<(ostream &out, const String &s);
public:
	String(const char* str = "")
	{
		m_data = new char[strlen(str) + 1];
		strcpy(m_data, str);
		m_count++;
	}
	String(const String& s)//淺拷貝
	{
		m_data = s.m_data;
		m_count++;
	}
	String& operator=(const String& s)
	{
		if (this != &s)
		{
			m_data = s.m_data;
			m_count++;
		}
		return *this;
	}
	~String()//淺賦值
	{
		if (--m_count == 0)
		{
			delete[]m_data;
			m_data = nullptr;
		}
	}
private:
	char* m_data;
	static int m_count;//引用計數(shù)器
};
int String::m_count = 0;

ostream& operator<<(ostream &out, const String &s)
{
	out << s.m_data;
	return out;
}

void main()
{
	String s1("abc");
	String s2 = s1;
	String s3;
	s3 = s2;
	cout << "s1 = " << s1 << endl;
	cout << "s2 = " << s2 << endl;
	cout << "s3 = " << s3 << endl;
}

可以看出,三個對象的m_data共享同一塊內(nèi)存空間,節(jié)省了資源;

但是暴露出了很多的問題:站在對象的角度,其中一個對象改變m_data其他的對象也會隨之改變;其二若s3使用其他字符串初始化,但計數(shù)器還是三者共享。

倘若我們使用深拷貝方法,就不會出現(xiàn)這種問題。如果可以在不改變m_data前使用淺拷貝,在改變時使用深拷貝,暨同時實現(xiàn)深淺拷貝,那么就兩全其美。

二、寫時拷貝

通過對上面問題的分析,我們需要實現(xiàn):引用計數(shù)器管理不同的空間。

class String_rep
{
public:
	String_rep(const char* str = "") :m_count(0)
	{
		m_data = new char[strlen(str) + 1];
		strcpy(m_data, str);
		cout << "creat" << endl;
	}
	String_rep(const String_rep &rep) :m_count(0)
	{
		m_data = rep.m_data;
		increment();
	}
	String_rep & operator=(const String_rep &rep)
	{
		if (this != &rep)
		{
			m_data = rep.m_data;
			increment();
		}
		return *this;
	}
public:
	void increment()
	{m_count++;}
	void decrement()
	{m_count--;} 
private:
	char* m_data;
	int m_count;
};
class String
{
public:
	String(const char* str = "") :pn(new String_rep(str))
	{
		pn->increment();
	}
	~String()
	{
		cout << "Free" << endl;
	}
private:
	String_rep *pn;
};
void main()
{
	String s1("abc");
}

拷貝構(gòu)造:s1和s2管理同一塊空間

定義s3,和s1、s2沒有關(guān)聯(lián);

我們再完全理一遍:

此時已經(jīng)解決我們之前提到過的第二個問題。

再來看第一個問題:

s1的改變影響了s2;

寫時拷貝:需要改變的時候深拷貝。

void to_upper()
	{
		String_rep *new_pn = new String_rep(pn->Getdata());//創(chuàng)建新空間
		pn->decrement();//原空間計數(shù)器減一
		pn = new_pn;//需要更改的對象的pn指向新空間
		pn->increment();//新空間的計數(shù)器加一
		char* p = pn->Getdata();
		while (*p != '\0')
		{
			if (*p >= 'a' && *p <= 'z')
				*p -= 32;
			p++;
		}

總結(jié)

到此這篇關(guān)于C++深淺拷貝和寫時拷貝的文章就介紹到這了,更多相關(guān)C++深淺拷貝 寫時拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你學習C++中的派生機制

    一文帶你學習C++中的派生機制

    C++是一門面向?qū)ο蟮木幊陶Z言,其中的派生機制是其重要的面向?qū)ο筇匦灾?。本文我們就來詳細地學習一下C++中的派生機制的相關(guān)知識吧
    2023-04-04
  • C++中的枚舉enum類型使用示例詳解

    C++中的枚舉enum類型使用示例詳解

    枚舉和類相似,能夠定義一種新的數(shù)據(jù)類型,不同的是,枚舉是將一組整形常量組織在一起,所以和類的使用方法有一些類似之處,這篇文章主要介紹了C++中的枚舉enum類型使用示例詳解,需要的朋友可以參考下
    2024-08-08
  • 詳解C語言基礎(chǔ)的類型轉(zhuǎn)換

    詳解C語言基礎(chǔ)的類型轉(zhuǎn)換

    這篇文章主要為大家介紹了C語言基礎(chǔ)的類型轉(zhuǎn)換,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • C/C++實現(xiàn)圖形學掃描線填充算法

    C/C++實現(xiàn)圖形學掃描線填充算法

    這篇文章主要介紹了C/C++實現(xiàn)圖形學掃描線填充算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C++拷貝構(gòu)造函數(shù)中的陷阱

    C++拷貝構(gòu)造函數(shù)中的陷阱

    這篇文章主要介紹了C++拷貝構(gòu)造函數(shù)中的陷阱,拷貝構(gòu)造函數(shù)大家都比較熟悉,通俗講就是傳入一個對象,拷貝一份副本。不過看似簡單的東西,實際不注意的話就會產(chǎn)生問題,下面我們就來看看C++拷貝構(gòu)造函數(shù)中都有哪些陷阱吧
    2022-01-01
  • C語言實現(xiàn)超市信息管理系統(tǒng)課程設(shè)計

    C語言實現(xiàn)超市信息管理系統(tǒng)課程設(shè)計

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)超市信息管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談VS中添加頭文件時顯示無法找到文件的問題

    淺談VS中添加頭文件時顯示無法找到文件的問題

    下面小編就為大家?guī)硪黄獪\談VS中添加頭文件時顯示無法找到文件的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Qt QML使用虛擬鍵盤的示例代碼

    Qt QML使用虛擬鍵盤的示例代碼

    這篇文章主要為大家詳細介紹了Qt QML使用虛擬鍵盤的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • C++實現(xiàn)帶頭雙向循環(huán)鏈表的示例詳解

    C++實現(xiàn)帶頭雙向循環(huán)鏈表的示例詳解

    這篇文章主要介紹了如何利用C++實現(xiàn)帶頭雙向循環(huán)鏈表,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-12-12
  • C++中使用哈希表(unordered_map)的一些常用操作方法

    C++中使用哈希表(unordered_map)的一些常用操作方法

    C++標準庫中使用的unordered_map底層實現(xiàn)是哈希表,下面這篇文章主要給大家介紹了關(guān)于C++中使用哈希表(unordered_map)的一些常用操作方法,需要的朋友可以參考下
    2022-03-03

最新評論