C++再議建構函式及複製建構函式深度複製
1、一般建構函式
如果沒有提供任何建構函式,建立一個什麼都不做的建構函式
如:
test::test()
{}
如果希望編譯器不使用這種預設的建構函式
可以自己定義預設建構函式
test::test()
{
...........;
}
當然也可以自己傳入值定義建構函式
test::test(const char* tin)
{
...........;
}
2、複製建構函式
它用於將一個物件複製到一個新建立的物件中,類的複製建構函式原型如下:
class_name(const class_name &);
關於複製建構函式下面幾種情況會使用到:
test my1(my); 顯示呼叫,my1是和my一樣的副本
test my1 = test(my); 顯示呼叫,my1是和my一樣的副本
test my1 = my; 隱試呼叫,my1是和my一樣的副本
void tf1(test t1);函式傳值生成臨時的類物件在函式中使用
test *p = new test(my);未測試
簡單的說程式生成了物件的副本,編譯器都會使用複製建構函式;既然是副本我們可以想象如果
類中定義的是指標型別,那麼指標指向的是同一片位置。如果此時呼叫解構函式會重複的釋放
同一片記憶體區域,同時如果不定義複製建構函式,那麼某些計數器將不你能正常工作。
另外我們注意同一段函式中如果類中有靜態物件如下:
private:
static int num_s;
使用
int charin::num_s = 0;
那麼在呼叫這個類的函式中多次呼叫它使用值是共享的因為是同一塊記憶體區域。這個其實和一般
的靜態內部變數沒什麼兩樣
我們來看一段程式碼
這段程式報錯如下:
gaopeng@bogon:~/CPLUSPLUS/part11/c2$ ./a.out
10 mem alloc!
study c++ in 1
test
8 bytes mem alloc!
test123 in 2
test here: test123
8 bytes mem release!
out 1
*** Error in `./a.out': double free or corruption (fasttop): 0x00000000021c1030 ***
Aborted (core dumped)
我使用的LINUX g++編譯器,可以看報錯double free or corruption,重複的釋放,其實這裡的計數器num_s也不能正常工作。
這種情況下我們必須要自己定義複製建構函式,使用深度複製而不是簡單的為指標型別資料複製指標的指向而已。
我們在程式中加入:
cf.cpp加入新函式 複製建構函式
接著我們再來跑一下我們的程式
10 mem alloc!
study c++ in 1
test
8 bytes mem alloc!
test123 in 2
8 bytes mem alloc!
test123 deep copy in 3
8 bytes mem alloc!
test123 deep copy in 4
test here: test123
8 bytes mem release!
test123 out 3
8 bytes mem release!
test123 out 2
8 bytes mem release!
test123 out 1
10 bytes mem release!
study c++ out 0
沒有問題了。
---endl---
如果沒有提供任何建構函式,建立一個什麼都不做的建構函式
如:
test::test()
{}
如果希望編譯器不使用這種預設的建構函式
可以自己定義預設建構函式
test::test()
{
...........;
}
當然也可以自己傳入值定義建構函式
test::test(const char* tin)
{
...........;
}
2、複製建構函式
它用於將一個物件複製到一個新建立的物件中,類的複製建構函式原型如下:
class_name(const class_name &);
關於複製建構函式下面幾種情況會使用到:
test my1(my); 顯示呼叫,my1是和my一樣的副本
test my1 = test(my); 顯示呼叫,my1是和my一樣的副本
test my1 = my; 隱試呼叫,my1是和my一樣的副本
void tf1(test t1);函式傳值生成臨時的類物件在函式中使用
test *p = new test(my);未測試
簡單的說程式生成了物件的副本,編譯器都會使用複製建構函式;既然是副本我們可以想象如果
類中定義的是指標型別,那麼指標指向的是同一片位置。如果此時呼叫解構函式會重複的釋放
同一片記憶體區域,同時如果不定義複製建構函式,那麼某些計數器將不你能正常工作。
另外我們注意同一段函式中如果類中有靜態物件如下:
private:
static int num_s;
使用
int charin::num_s = 0;
那麼在呼叫這個類的函式中多次呼叫它使用值是共享的因為是同一塊記憶體區域。這個其實和一般
的靜態內部變數沒什麼兩樣
我們來看一段程式碼
點選(此處)摺疊或開啟
-
::::::::::::::
-
c2.h
-
::::::::::::::
-
/*************************************************************************
-
> File Name: c2.h
-
> Author: gaopeng
-
> Mail: gaopp_200217@163.com
-
> Created Time: Fri 24 Jun 2016 01:47:19 AM CST
-
************************************************************************/
-
-
#include<iostream>
-
using namespace std;
-
-
class charin
-
{
-
private:
-
static int num_s;
-
char* sin;
-
int len;
-
public:
-
charin(void);
-
charin(const char *);
-
//charin(charin &);
-
~charin(void);
-
friend std::ostream & operator<<(std::ostream &,const charin &);
-
};
-
::::::::::::::
-
cf.cpp
-
::::::::::::::
-
/*************************************************************************
-
> File Name: cf.cpp
-
> Author: gaopeng
-
> Mail: gaopp_200217@163.com
-
> Created Time: Fri 24 Jun 2016 01:59:13 AM CST
-
************************************************************************/
-
-
#include<iostream>
-
#include<string.h>
-
#include"c2.h"
-
using namespace std;
-
-
int charin::num_s = 0;
-
-
charin::charin(void)
-
{
-
len = strlen("study c++")+1;
-
cout << len <<" mem alloc!"<<endl;
-
sin = new char[len];
-
strcpy(sin,"study c++");
-
num_s++;
-
cout << sin <<" in "<<num_s<<endl;
-
}
-
charin::charin(const char* sorstr )
-
{
-
len = strlen(sorstr)+1;
-
cout << len <<" bytes mem alloc!"<<endl;
-
sin = new char[len];
-
strcpy(sin,sorstr);
-
num_s++;
-
cout << sin <<" in "<<num_s<<endl;
-
}
-
charin::~charin(void)
-
{
- num_s--;
-
cout << len <<" bytes mem release!"<<endl;
-
cout << sin <<" out "<<num_s<<endl;
- delete [] sin;
-
}
-
std::ostream & operator<<(std::ostream & os,const charin & cin)
-
{
-
os << cin.sin;
-
return os;
-
}
-
-
::::::::::::::
-
main.cpp
-
::::::::::::::
-
/*************************************************************************
-
> File Name: main.cpp
-
> Author: gaopeng
-
> Mail: gaopp_200217@163.com
-
> Created Time: Fri 24 Jun 2016 02:23:51 AM CST
-
************************************************************************/
-
-
#include<iostream>
-
#include"c2.h"
-
using namespace std;
-
-
-
void chmi(charin );
-
-
int main(void)
-
{
-
const char *testc = "test123";
-
charin t1;
-
cout <<"test"<<endl;
-
charin t2(testc);
-
charin t3 = t2; //error
-
chmi(t2); //error
-
-
}
-
-
//error beacause pointer sin pointer same point;
-
void chmi(charin a)
-
{
-
cout<<"test here: "<<a<<endl;
- }
gaopeng@bogon:~/CPLUSPLUS/part11/c2$ ./a.out
10 mem alloc!
study c++ in 1
test
8 bytes mem alloc!
test123 in 2
test here: test123
8 bytes mem release!
out 1
*** Error in `./a.out': double free or corruption (fasttop): 0x00000000021c1030 ***
Aborted (core dumped)
我使用的LINUX g++編譯器,可以看報錯double free or corruption,重複的釋放,其實這裡的計數器num_s也不能正常工作。
這種情況下我們必須要自己定義複製建構函式,使用深度複製而不是簡單的為指標型別資料複製指標的指向而已。
我們在程式中加入:
點選(此處)摺疊或開啟
-
c2.h 加入
-
-
#include<iostream>
-
using namespace std;
-
-
class charin
-
{
-
private:
-
..........
-
public:
-
..........
-
charin(charin &); //加入
-
.........
-
};
cf.cpp加入新函式 複製建構函式
-
charin::charin(charin &in)
-
{
-
len = in.len;
-
sin = new char[len];
-
strcpy(sin,in.sin);
-
num_s++;
-
cout << len <<" bytes mem alloc!"<<endl;
- cout << sin <<" deep copy in "<<num_s<<endl;
- }
10 mem alloc!
study c++ in 1
test
8 bytes mem alloc!
test123 in 2
8 bytes mem alloc!
test123 deep copy in 3
8 bytes mem alloc!
test123 deep copy in 4
test here: test123
8 bytes mem release!
test123 out 3
8 bytes mem release!
test123 out 2
8 bytes mem release!
test123 out 1
10 bytes mem release!
study c++ out 0
沒有問題了。
---endl---
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2121213/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++複製建構函式C++函式
- 預設建構函式、引數化建構函式、複製建構函式、解構函式函式
- 深度解讀《深度探索C++物件模型》之複製建構函式C++物件模型函式
- C++ 移動構造和複製建構函式匹配C++函式
- 物件的生存期 記憶體 深度複製 複製建構函式 筆記物件記憶體函式筆記
- C++ 禁用類的複製建構函式和賦值運算子C++函式賦值
- C++ 建構函式和解構函式C++函式
- 結構體中的指標&&複製賦值建構函式改造結構體指標賦值函式
- 【C/C++】為什麼需要複製建構函式的同時通常也需要過載複製運算子C++函式
- 【C++】初始化列表建構函式VS普通建構函式C++函式
- C++入門記-建構函式和解構函式C++函式
- C++中建構函式,拷貝建構函式和賦值函式的詳解C++函式賦值
- C++ 建構函式實戰指南:預設構造、帶引數構造、複製構造與移動構造C++函式
- 建構函式與解構函式函式
- ## 建構函式函式
- 類的建構函式和解構函式函式
- JavaScript 建構函式JavaScript函式
- 建構函式、原型及原型鏈函式原型
- C++建構函式和解構函式呼叫虛擬函式時使用靜態聯編C++函式
- PHP筆記:建構函式與解構函式PHP筆記函式
- C++拷貝建構函式詳解C++函式
- C++型別轉換建構函式C++型別函式
- c++ 的學習 建構函式1C++函式
- 迴圈單連結串列建構函式、解構函式C++實現函式C++
- 11-建構函式函式
- 初識建構函式函式
- JavaScript Date()建構函式JavaScript函式
- 建構函式建立物件函式物件
- 建構函式詳解函式
- 建構函式和類函式
- 關於建構函式與解構函式的分享函式
- 深度解讀《深度探索C++物件模型》之預設建構函式C++物件模型函式
- 建構函式與普通函式的區別函式
- 【譯】JavaScript 工廠函式 vs 建構函式JavaScript函式
- C++——建構函式之初始化列表C++函式
- C++:建構函式的分類和呼叫C++函式
- constructor 未指向建構函式Struct函式
- 回顧Javascript建構函式JavaScript函式
- JS 建構函式與類JS函式