本文目錄一覽:
- 1、JAVA中有沒有缺省的拷貝構造函數
- 2、拷貝構造函數在哪幾種情況下調用
- 3、java中有拷貝構造函數的概念嗎?方法傳遞對象時一般如何避免副作用?
- 4、拷貝構造函數的作用
- 5、java中構造方法和拷貝構造方法是什麼意思
JAVA中有沒有缺省的拷貝構造函數
java中有缺省的拷貝構造函數,具體參考下面的代碼:
//Example:
//1.Clock類:
public class Clock {
private int hour;
private int minute;
private int second;
public Clock(){
setTime(0,0,0);
}
public Clock(int h,int m,int s){
setTime(h,m,s);
}
/* 拷貝構造函數 */
public Clock(Clock clock){
this.hour=clock.hour;
this.minute=clock.minute;
this.second=clock.second;
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public int getSecond() {
return second;
}
public void setTime(int h,int m,int s){
if(h=0 h24)
this.hour=h;
else
this.hour=0;
if(m=0 m60)
this.minute=m;
else
this.minute=0;
if(s=0 s60)
this.second=s;
else
this.second=0;
}
public void printTime(){
if(this.hour10)
System.out.print(“0”);
System.out.print(this.hour+”:”);
if(this.minute10)
System.out.print(“0”);
System.out.print(this.minute+”:”);
if(this.second10)
System.out.print(“0”);
System.out.println(this.second);
}
}
//2.main函數:
public class Program {
public static void main(String[] args) {
Clock c1=new Clock(6,43,23);
Clock c2=new Clock(c1);//調用拷貝構造函數
c1.printTime();
c2.printTime();
}
}
//3.運行結果:
06:43:23
06:43:23
拷貝構造函數在哪幾種情況下調用
有時候需要自己定義拷貝構造函數,以避免淺拷貝問題。
在什麼情況下需要用戶自己定義拷貝構造函數:
一般情況下,當類中成員有指針變量、類中有動態內存分配時常常需要用戶自己定義拷貝構造函數。
在什麼情況下系統會調用拷貝構造函數:(三種情況)
(1)用類的一個對象去初始化另一個對象時
(2)當函數的形參是類的對象時(也就是值傳遞時),如果是引用傳遞則不會調用
(3)當函數的返回值是類的對象或引用時
#include iostream
using namespace std;
class A
{
private:
int a;
public:
A(int i){a=i;} //內聯的構造函數
A(A aa);
int geta(){return a;}
};
A::A(A aa) //拷貝構造函數
{
a=aa.a;
cout”拷貝構造函數執行!”endl;
}
int get_a(A aa) //參數是對象,是值傳遞,會調用拷貝構造函數
{
return aa.geta();
}
int get_a_1(A aa) //如果參數是引用類型,本身就是引用傳遞,所以不會調用拷貝構造函數
{
return aa.geta();
}
A get_A() //返回值是對象類型,會調用拷貝構造函數。會調用拷貝構造函數,因為函數體內生成的對象aa是臨時的,離開這個函數就消失了。所有會調用拷貝構造函數複製一份。
{
A aa(1);
return aa;
}
A get_A_1() //會調用拷貝構造函數,因為函數體內生成的對象aa是臨時的,離開這個函數就消失了。所有會調用拷貝構造函數複製一份。
{
A aa(1);
return aa;
}
int _tmain(int argc, _TCHAR* argv[])
{
A a1(1);
A b1(a1); //用a1初始化b1,調用拷貝構造函數
A c1=a1; //用a1初始化c1,調用拷貝構造函數
int i=get_a(a1); //函數形參是類的對象,調用拷貝構造函數
int j=get_a_1(a1); //函數形參類型是引用,不調用拷貝構造函數
A d1=get_A(); //調用拷貝構造函數
A e1=get_A_1(); //調用拷貝構造函數
return 0;
java中有拷貝構造函數的概念嗎?方法傳遞對象時一般如何避免副作用?
我也是找的,希望幫到你。
在C++中,下面三種對象需要調用拷貝構造函數(有時也稱“複製構造函數”)
1) 一個對象作為函數參數,以值傳遞的方式傳入函數體
2) 一個對象作為函數返回值,以值傳遞的方式從函數返回
3) 一個對象用於給另外一個對象進行初始化(常稱為複製初始化)
當用引用變量做參數時,不調用拷貝構造函數,用傳遞引用的方式給函數傳遞一個對象的引用時,只傳遞了該對象的地址,系統消耗較小。在函數體內訪問 形參,實際是訪問了這個作為實參的對象。例如:void function(CTest test);
Java中的引用傳遞是指: 例如:void function(CTest test),沒有號
通常的原則是:①對於凡是包含動態分配成員或包含指針成員的類都應該提供拷貝構造函數;②在提供拷貝構造函數的同時,還應該考慮重載”=”賦值操作符號。
具體過程:首先建立對象theObjtwo,並調用其構造函數,然後成員被複制初始化。
其完成方式是內存拷貝,複製所有成員的值。完成後,theObjtwo.pBuffer==theObjone.pBuffer。
即它們將指向同樣的地方,指針雖然複製了,但所指向的空間並沒有複製,而是由兩個對象共用了。這樣不符合要求,對象之間不獨立了,並為空間的刪除帶來隱患。所以需要採用必要的手段來避免此類情況:可以在構造函數中添加操作來解決指針成員的這種問題。
所以C++語法中除了提供缺省形式的構造函數外,還規範了另一種特殊的構造函數:拷貝構造函數,一種特殊的構造函數重載。上面的語句中,如果類中定義了拷貝構造函數,在對象複製初始化時,調用的將是拷貝構造函數,而不是缺省構造函數。在拷貝構造函數中,可以根據傳入的變量,複製指針所指向的資源。
拷貝構造函數的格式為:類名(const 類名 對象名);//拷貝構造函數的原型,參數是常量對象的引用。由於拷貝構造函數的目的是成員複製,不應修改原對象,所以建議使用const關鍵字。
下面介紹拷貝構造函數的另一種調用:當對象直接作為參數傳給函數時,函數將建立對象的臨時拷貝,這個拷貝過程也將調用拷貝構造函數。
總結:當某對象是按值傳遞時(無論是作為函數參數,還是作為函數返回值),編譯器都會先建立一個此對象的臨時拷貝,而在建立該臨時拷貝時就會調用類的拷貝構造函數。
拷貝構造函數的實現:
類名::類名(類名對象名)//拷貝構造函數的實現/定義
拷貝構造函數的作用
用一個已有的對象來初始化一個被創建的同類的對象,是一種特殊的構造函數,具有一般構造函數的所有特性,其形參是本類對象的引用。
用戶可以根據自己實際問題的需要定義特定的拷貝構造函數,以實現同類對象之間數據成員的傳遞。如果用戶沒有聲明類的拷貝構造函數,系統就會自動生成一個缺省拷貝構造函數,這個缺省拷貝構造函數的功能是把初始對象的每個數據成員的值都複製到新建立的對象中。
擴展資料
拷貝構造函數使用原則:對於凡是包含動態分配成員或包含指針成員的類都應該提供拷貝構造函數;在提供拷貝構造函數的同時,還應該考慮重載“=”賦值操作符號。
傳遞形式:拷貝構造函數必須以引用的形式傳遞(參數為引用值)。其原因如下:當一個對象以傳遞值的方式傳一個函數的時候,拷貝構造函數自動的被調用來生成函數中的對象。
如果一個對象是被傳入自己的拷貝構造函數,它的拷貝構造函數將會被調用來拷貝這個對象這樣複製才可以傳入它自己的拷貝構造函數,這會導致無限循環直至棧溢出(Stack Overflow)。除了當對象傳入函數的時候被隱式調用以外,拷貝構造函數在對象被函數返回的時候也同樣的被調用。
參考資料來源:百度百科-拷貝構造函數
參考資料來源:百度百科-深拷貝
java中構造方法和拷貝構造方法是什麼意思
構造函數只能進行淺copy,就是只能複製簡單類型如int,float數據到另一副本。
如果對象中包含了對象等複雜類型,淺拷貝對象其實是對象的引用,而不是重新生成一個新副本。這時,如果對一個實例的內部類類型修改,其他實例的內部類類型也會被修改。這時就需要copy構造函數來進行深複製(也就是使對象中包含的類等複雜類型使用值賦值,而不是引用賦值)。
原創文章,作者:HTXU,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/148841.html