1. 程式人生 > >c++的建構函式極其呼叫(無參建構函式,有參建構函式,拷貝建構函式)

c++的建構函式極其呼叫(無參建構函式,有參建構函式,拷貝建構函式)

1.c++編譯器會自動呼叫建構函式

//建構函式(與類名相同)
//解構函式:沒有引數也沒有任何返回型別,被自動呼叫
#include<iostream>
using namespace std;
class Test
{
public:
	Test();//無參建構函式
	~Test();//解構函式:先建立的物件後釋放
	void print()
	{
		cout << a << endl;
		cout << p << endl;
	}
private:
	int a;
	char *p;
};

Test::Test()//完成對屬性的初始化工作
{
	a = 10;
	p = (char*)malloc(sizeof(100));
	strcpy(p, "Rita");
	cout<< "我是建構函式" << endl;
}

Test::~Test()
{
	if (p != NULL)
	{
		free(p);
	}
	cout << "我是解構函式,我被呼叫了" << endl;
}
//給物件搭建一個平臺,研究物件的行為
void objplay()
{
	//先建立的物件後釋放
	Test t1;
	t1.print();
	printf("分隔符\n");
	Test t2;
	t2.print();
}
int main()
{
	objplay();
	system("pause");
	return 0;
}

分析:先呼叫t1的無參建構函式,再呼叫print(),再呼叫t2的無參建構函式,再呼叫print(),最後先呼叫t2的解構函式,因為分配的記憶體在棧裡,先入棧的後出棧,所以先定義的後釋放,後呼叫解構函式。

2.拷貝建構函式的呼叫(三種方法)

#include<iostream>
using namespace std;
//類的建構函式的分類:無參建構函式。有參建構函式。拷貝建構函式
class Test2
{
public:
	Test2()//無參建構函式
	{
		m_a = 0;
		m_b = 0;
		cout << "無參建構函式" << endl;
	}
	Test2(int a)
	{
		m_a = a;
		m_b = 0;
	}
	Test2(int a, int b)
	{
		m_a = a; m_b = b;
		cout << "有參建構函式"<< endl;
	}
	//copy建構函式
	Test2(const Test2& obj)
	{
		cout << "我也是建構函式"<< endl;
	}
public:
	void print()
	{
		cout << "普通成員函式"<< endl;
	}
private:
	int m_a;
	char m_b;
};

int main04()//呼叫無參建構函式
{
	Test2 t1;
	system("pause");
	return 0;
}
int main()//呼叫有參建構函式
{
	//1.括號法
	Test2 t1(1, 2);//呼叫引數建構函式,c++編譯器自動呼叫
	t1.print();
	//2.=號法
	Test2 t2 = (1, 2, 3, 4, 5);//= c++對等號符功能增強,c++編譯器自動的呼叫建構函式
	Test2 t3 = 5;
	//3.直接呼叫建構函式,手動的呼叫建構函式
	Test2 t4 = Test2(1, 2);//匿名物件的去和留,後面會說
	t1 = t4;//賦值操作:把t4copy給t1,物件的初始化和物件的賦值是兩個不同的概念

	system("pause");
	return 0;
}

3.拷貝建構函式的呼叫

#include<iostream>
using namespace std;
//建構函式的呼叫
class Test4
{
public:
	Test4()//無參建構函式
	{
		m_a = 0;
		m_b = 0;
		cout << "無參建構函式" << endl;
	}
	Test4(int a)
	{
		m_a = a; m_b = 0;
	}
	Test4(int a, int b)
	{
		m_a = a; m_b = b;
		cout << "有參建構函式" << endl;
	}
	//copy建構函式
	Test4(const Test4& obj)
	{
		cout << "我也是建構函式" << endl;
		m_a = obj.m_a + 100;//雖然是拷貝建構函式,也不是完全拷貝,可以根據自己的意願拷貝(+100)
		m_b = obj.m_b + 100;
	}
public:
	void print()
	{
		cout << "普通成員函式" << endl;
		cout << m_a << m_b << endl;
	}
private:
	int m_a;
	int m_b;
};

int main06()
{
	Test4 t1(1, 2);
	Test4 t0(1, 2);
	t0 = t1;//不會呼叫拷貝建構函式
	//第一種呼叫方法
	Test4 t2 = t1;//用t1初始化t2,此時會呼叫拷貝建構函式
	t2.print();

	system("pause");
	return 0;
}
//第二種呼叫時機
int main()
{
	Test4 t1(1, 2);
	Test4 t0(1, 2);
	Test4 t2(t1);// t1初始化t2,此時會呼叫拷貝建構函式
	t2.print();

	system("pause");
	return 0;
}

4.形參是一個元素,b實參去初始化形參p,會呼叫copy建構函式

#include<iostream>
using namespace std;
class Location
{
public:
	Location(int xx = 0,int yy=0)
	{
		X = xx;
		Y = yy;
		cout << "Constructor Object\n" << endl;
	}
	//copy建構函式完成物件的初始化
	Location(const Location& obj)
	{
		X = obj.X;
		Y = obj.Y;
	}
	~Location()
	{
		cout << "Destroyed\n" << endl;
	}
	int getX()
	{
		return X;
	}
	int getY()
	{
		return Y;
	}
private:
	int X;
	int Y;
};
//形參是一個元素(不是指標也不是引用),當呼叫此函式時,c++編譯器會自動呼叫copy建構函式,用實參初始化形參
void f(Location p)
{
	cout << p.getX() << endl;
}
void playobj()
{
	Location a(1, 2);
	Location b = a;
	cout << "物件初始化完畢" << endl;
	f(b);
}
int main()
{
	playobj();
	system("pause");
	return 0;
}

5.關於匿名物件的去和留(匿名物件是否會被析構)

#include<iostream>
using namespace std;
class Location
{
public:
	Location(int xx = 0, int yy = 0)
	{
		X = xx;
		Y = yy;
		cout << "Constructor Object\n" << endl;
	}
	//copy建構函式完成物件的初始化
	Location(const Location& obj)
	{
		X = obj.X;
		Y = obj.Y;
	}
	~Location()
	{
		cout << "Destroyed\n" << endl;
	}
	int getX()
	{
		return X;
	}
	int getY()
	{
		return Y;
	}
private:
	int X;
	int Y;
};
//g()函式 返回一個元素
//結論1.函式的返回值是一個元素(複雜資料型別),返回的是一個新的匿名物件
//如果用匿名物件初始化另一個同類型物件,匿名物件轉化成有名物件,不會被析構
//如果匿名物件賦值給另一個同類型物件,匿名物件被析構
Location g()
{
	Location A(1, 2);
	return A;//返回一個新的物件,沒有名字
}
void objPlay1()
{
	g();
}
void objPlay2()
{
	//用匿名物件初始化m,此時c++編譯器直接把匿名物件扶正,不會被析構
	Location m = g();
	cout << m.getX() << endl;
}
void objPlay3()
{
	//用匿名物件賦值給m2之後,匿名物件被析構
	Location m2(1, 2);
	m2 = g();//這不是初始化,這是賦值
	cout << m2.getX() << endl;
}
int main()
{
	//objPlay1();//執行結果1.Constructor Object2.Destroyed3.Destroyed
	//objPlay2();//執行結果1.Constructor Object2.Destroyed(析構A)3. 1  4.Destroyed(析構m)
	objPlay3();//執行結果1.Constructor Object(建立m2)2.Constructor Object(建立A)3.Destroyed(析構A)4.Destroyed(析構匿名物件)5.  1   6..Destroyed(析構m2)
	system("pause");
	return 0;
}

相關推薦

c++的建構函式極其呼叫建構函式建構函式拷貝建構函式

1.c++編譯器會自動呼叫建構函式//建構函式(與類名相同) //解構函式:沒有引數也沒有任何返回型別,被自動呼叫 #include<iostream> using namespace std; class Test { public: Test();//無參建

C++建立類物件時後不加括號與加括號的區別

https://blog.csdn.net/Windgs_YF/article/details/80927058 https://blog.csdn.net/u012750259/article/details/44832769 1、在棧中例項化物件 A a;//例項化物件,會呼叫c

函式的宣告和呼叫函式函式

函式的宣告和變數的宣告差不多是一個意思 例如宣告一個變數是:var aa; 宣告一個函式則為:function aa(){}//表示聲明瞭一個函式名為aa的函式變數的使用與函式的呼叫意思也差不多 例如:var aa=1;alert(aa); 例如函式的呼叫:functio

swift 自定義類的建構函式構造、構造

import UIKit class person : NSObject { var name : String? var age : Int = 0 //1.重寫

Python與C之間的相互呼叫Python C API及Python ctypes庫

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

20181130裝飾器補充疊加多個裝飾器裝飾器三元表示式生成式匿名函式內建函式

  一、裝飾器的補充 1、函式屬性的傳遞 Python裝飾器(decorator)在實現的時候,被裝飾後的函式其實已經是另外一個函數了(函式名等函式屬性會發生改變),為了不影響,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用。寫一個decora

函式呼叫彙編程式碼分析

1.sum函式呼叫完為什麼會回退到main函式的呼叫棧針上。 2.為什麼呼叫完後會從下一行執行。 3.值是怎麼傳遞的,是形參開闢記憶體,還是實參開闢。 # include<stdio.h> int sum(int first,int second)

LLVM與C++程式碼的相互呼叫全註釋

一、在C++中呼叫LLVM編寫的IR函式 #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Function.h" #include "llvm/IR/BasicBlock.h" #i

構造方法和構造方法的呼叫

/*無參構造方法和有參構造方法*/ class Person8{private String name;private int age;public Person8(){System.out.println("呼叫了無參構造方法。。。");}public  Person8(

Qt - QDialog,QWidget實現模態及非模態模態Widget不能父窗口如果設置邊框就不能阻塞父窗口但是可以強行設置指定Qt::Dialog還可以setAttribute(Qt::WA_ShowModal)很多講究good

col set print png 運行時 操作 qwidget 對話 idg 在Qt中QDialog為“窗口”,而QWidget為“部件”,首先還是了解下《Qt 窗口與部件的概念》。 對於 QDialog 的模態及非模態是

python中的裝飾器和裝飾器

tools mysql認證 ati 轉載 lan 單獨 get 原則 url                   python中的無參裝飾器和有參裝飾器                                        作者:尹正傑 版權聲明:原創作品,謝絕轉載

SSM Controller 頁面之間跳轉 重定向 問題

url ssm AS some jsp 使用方法 map res exc 需求:spring MVC框架controller間跳轉,需重定向。有幾種情況:不帶參數跳轉,帶參數拼接url形式跳轉,帶參數不拼接參數跳轉,頁面也能顯示。 (1)我在後臺一個cont

Python-23_裝飾器-04_練習---裝飾器、裝飾器

一、無參裝飾器: 京東後端程式簡寫,並加上驗證功能:編寫一個裝飾器,提供驗證功能: # 使用者資訊表: user_list=[ {'name':'new1','passwd':'123'}, {'name':'new2','passwd':'123'}, {'name':'n

20181130裝飾器補充疊加多個裝飾器裝飾器三元表達式生成式匿名函數內置函數

names hello 對應關系 tools src recv log 原始的 裝飾 一、裝飾器的補充 1、函數屬性的傳遞 Python裝飾器(decorator)在實現的時候,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變),為了不影響,Pytho

C 判斷 —— if...else 語句bool變數、float變數、指標變數與“零值”進行比較(else 到底與哪個 if 配對呢? if 語句後面的分號?)

1、bool 變數與“零值”進行比較 bool 變數與“零值”進行比較的 if 語句怎麼寫? bool bTestFlag = FALSE;//想想為什麼一般初始化為 FALSE 比較好? A), if(bTestFlag == 0); if(bTestFlag == 1

R語言︱函式使用技巧迴圈、if族/for、switch、repeat、ifelse、stopifnot

每每以為攀得眾山小,可、每每又切實來到起點,大牛們,緩緩腳步來俺筆記葩分享一下吧,please~———————————————————————————後續加更內容:應用一:if族有哪些成員呢?——if/ifelse/stopifnot應用二:如何在迴圈中,實時輸出時間消耗?—

java中構造方法的理解super()與構造方法構造方法this()與構造方法。

一、為什麼要引入構造方法。 當建立物件的時候需要對屬性值初始化,構造方法,即物件建立時要執行的方法。 要求在例項化的同時,就指定好name,和age的值。這就要用到構造方法。又叫做構造器Constructor. 二、構造方法的定義格式 構造方法在new的時候自動執行。且只執

長春牙齒矯正日記第三篇-----------戴上牙套看牙竟然還會降價?這是什麼操作?

距離上次更新已經一個月了,一個月後,牙套終於到了,約了下午一點的時間,花了大約一個多小時,本來以為可能會有些疼痛,慶幸的是,真的還不怎麼疼,只是有些難受而已,一個小時,總是張著嘴,牙醫在你的嘴裡搞來搞去,當然不會很舒服的,啊啊啊啊啊啊啊啊。 這次主要就是粘了一個掛槽,以便可

A/B 測試的基本概念舉例理解以及具體實現方法【傳統A/B測試基於後端的 A/B 測試Back-end AB test現在基本上基於前端js在客戶端進行分流更多優點請看裡面】

文章來源:http://www.aliued.cn/2010/09/27/ab-testing-realization-method.html 什麼是A/B測試?以及如何進行? 很多朋友都問我怎麼進行A/B測試,我一般都不直接回答他們的問題,而是首先問一句:“你的日