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

C++深淺拷貝和寫時(shí)拷貝圖文詳解

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

前言

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

一、深淺拷貝哪家強(qiáng)?

先給出代碼理一理

#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;
}

而我們之前所說的淺拷貝崩潰是因?yàn)閐oublefree的問題,因此我們可以定義一個(gè)引用計(jì)數(shù)器,來記錄當(dāng)前使用該值的對象數(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;//引用計(jì)數(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;
}

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

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

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

二、寫時(shí)拷貝

通過對上面問題的分析,我們需要實(shí)現(xiàn):引用計(jì)數(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);

我們再完全理一遍:

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

再來看第一個(gè)問題:

s1的改變影響了s2;

寫時(shí)拷貝:需要改變的時(shí)候深拷貝。

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

總結(jié)

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

相關(guān)文章

  • 一文帶你學(xué)習(xí)C++中的派生機(jī)制

    一文帶你學(xué)習(xí)C++中的派生機(jī)制

    C++是一門面向?qū)ο蟮木幊陶Z言,其中的派生機(jī)制是其重要的面向?qū)ο筇匦灾?。本文我們就來詳?xì)地學(xué)習(xí)一下C++中的派生機(jī)制的相關(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)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • C/C++實(shí)現(xiàn)圖形學(xué)掃描線填充算法

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論