C++语言入门(三)构造析构函数

一.构造函数

  • 在对象被创建时自动执行
  • 可以有多个构造函数

调用时机:

1.对象直接定义创建--构造函数不能被显式调用(栈)

2.new动态创建(堆)

例:定义一个账单 

#include<iostream>
#include<vector>
#include<string>
using namespace std;

class Bill{
private:
	string name;
	int count;
	float price;
public:
	Bill(string n,int c,float p){//构造函数 ,不用Init了 
		name = n;
		count = c;
		price = p;
	}
	string GetName(){ return name; }
	int GetCount(){ return count; }
	float GetPrice(){ return price; }
	float GetTotal(){ return count*price; }
};

class Account{
private:
	vector<Bill> bills;
public:
	void Add(Bill bill){
		bills.push_back(bill);//把bill尾插入bills中 
    }
    void Print(){
		cout << "name\tcount\tprice\ttotal" << endl;
		cout << "-----------------------------" << endl;
		float sum = 0;
		for(int i=0;i<bills.size();++i){
			cout << bills[i].GetName() << "\t";
			cout << bills[i].GetCount() << "\t";
			cout << bills[i].GetPrice() << "\t";
			cout << bills[i].GetTotal() << endl;
			sum += bills[i].GetTotal();
		}
		cout << "-----------------------------" << endl;
		cout <<"Total:\t\t\t" << sum << endl;//"\t"是tab键,使对齐 
    }
};

int main(){
	Account account;
	//堆上定义:
	Bill* p = new Bill("Banana",3,2.3);
	account.Add(*p);
	delete p;
    p = NULL;
	  
	//栈上定义: 
	Bill a("Apple",10,2.5);//直接初始化 
	Bill b("Orange",5,3);
	Bill c("Pair",4,3.6);
    account.Add(Bill("grape",5,2.99)); //也可以直接赋值调用,匿名对象
	account.Add(a); 
	account.Add(b);
	account.Add(c);
	account.Print();
}

默认构造函数: 

 类中没有显式的定义任何构造函数,编译器就会自动为该类型生成默认构造函数,默认构造函数没有参数。 例:最后输出为:Simple()x4

class Simple{
public:
	Simple(){
		cout << "Simple()" << endl;
	}
};
int main(){
	Simple s;
    Simple arr[3];
}

例:如上一段代码,若在int main()中直接写 Bill p;则将会报错,因为已经定义过构造函数了,没有默认构造函数了。

若定义数组,则在类里写一个,默认构造函数,例:

class Bill{
public:
	Bill(){
		name = " ";
		count = 0;
		price = 0;
	}
	Bill(string n,int c,float p){
		name = n;
		count = c;
		price = p;
	}
};
int main(){
	Bill bills[3];//会调用第一个构造函数,一次性定义三个变量 
	Bill a("Apple",10,2.5);//会调用第二个构造函数 
}

或者,不用再写新的构造函数,初始化时写成数组形式

Bill bills[3] = {
		Bill("a",1,2),
		Bill("b",3,4),
		Bill("c",5,6)
};
for(int i=0;i<3;i++){
		account.Add(bills[i]); 
}

构造函数的三个作用

  • 给创建的对象建立一个标识符
  • 为对象数据成员开辟内存空间
  • 完成对象数据成员的初始化

初始化列表 

类名(参数):成员变量(参数){
  函数体
}

可以有很多成员变量 

例:输出为 Simple(10) Simple(100)

class Simple{
public:
	Simple(){
		cout << "Simple("<< n <<")" << endl;
	}
};
class SimpleWrapper{
Simple s;
public:
	SimpleWrapper(int n):s(n){
		// s = Simple(n);
	}
};
int main(){
	Simple s(10);
	SimpleWrapper sw(100);
}

默认参数: 

#include<iostream>
using namespace std;

class Simple{
int n;
public:
	// Simple():n(0){}
	Simple(int n = 0):n(n){//默认参数为0(当没写参数时),合并了默认构造函数 
		cout << __func__ << "(" << n << ")" <<endl; //__func__为输出函数名(Simple) 
	}
	void Print(){
		cout << __func__ << "():" << n << endl;//__func__为Print 
	}
};
int main(){
	Simple s(10);
	s.Print();
	
	Simple* p = new Simple(20);
	p->Print();

    Simple s2;
	Simple* p2 = new Simple;
}

 当把实现和声明拆开时,实现中写int n = 0; 声明中不用写,但可以写/*=0*/来注释。

二.析构函数

 作用:释放对象所申请占有的资源

当每次申请了新的内存后,要再释放,每次都delete太麻烦了,所以有了析构函数

#include<iostream>
using namespace std;

class Simple{
int* p;
public:
	Simple(int n):p(new int(n)){//p为指针,申请一块内存 
		cout << __func__ << endl;
		// p = new int(n);
	}
	void Print(){
		cout << *p << endl;
	}
	~Simple(){//析构函数,在作用域最后自动调用(栈上),因为栈会自动释放内存
	    cout << __func__ << endl;//检验是否调用 
		delete p;
		p = NULL;
	}
};
int main(){
	{
	Simple s(10);
	s.Print();
    }
	Simple* p = new Simple(20);
	p->Print();
	delete p;//因为内存是我们手动申请的,所以不能自动释放,调用不了析构函数 
}
  • 析构函数的函数名与类名相同
  • 函数名前必须有一个~
  • 没有参数
  • 没有返回值类型、也没有返回值
  • 只能有一个析构函数

默认析构函数

类中没有显式的定义析构函数,编译器就会自动为该类型生成默认析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值