类的构造和析构函数(1)

stcok类样例:

class stock
{
private:
	std::string company;
	long sharee;
	double share_val;
	double total_val;
	void set_tot(){ total_val=shares*share_val;}
public:
	void acquire(const std::string &co,long n,double pr);
	void buy(long sum,double price);
	void sell(long sum,double price);
	void update(double price);
	void show();
	}

`在cpp中class类型无法像int或者结构一样初始化,为此cpp提供了一个特殊的成员函数——构造函数,专门用于创造新的对象,并将值赋给它们的数据成员。
1.1声明和定义构造函数
函数原型:

stock(const string &co,long n=0,double pr=0.0)

****注意:****尽管没有返回值,但是stock并没有被声明为void类型,实际上,构造函数没有声明类型。函数原型位于类声明的公有部分。
下面是构造函数的一个可能定义:

stock::stock (const string &co,long n,double pr)
{
	company=co;
	if(n<0)
	{
		std::cerr<<"Number of shares can not be negative:"
						<<company<<"shares set to be 0.\n"
		shares=0;
	}
	else
		shares=n;
	share_val=pr;
	set_tot();
	}

构造函数与其他成员函数类似,区别在于,程序在声明对象时,将自动调用构造函数。
***注意:***不能使用类成员名称来作为构造函数的参数名字
//NO

stock::stock(const string &company,long shares,double share_val)
{
---
}

这是错误的,构造函数表示的不是类成员本身,而是付给类成员的值,所以参数名不能与类成员相同,否则最终的代码将是这样的:

shares=shares;

为了避免这样的混乱,一种常见的作法是在数据成员中使用m_前缀:

class stock
{
private:
 	string m_company;
 	long m_shares;
 	.....

另一种常见的作法就是,在数据成员中使用_后缀:

class stock{
private
	string company_;
	long shares_
	......

无论采取哪种作法,都可以在公有接口中在参数名中包含company和share
1.2 使用构造函数
cpp提供了两种调用构造函数的方法:
第一种是显示调用:

stock garment=stock("world cat",250,1.25)

另一种是隐式调用:

stcok garment("world cat",80,1.25)

构造函数也可以和new一起使用:

stock *postcat=new stock("worldcat",60,1.25);

这条语句,创建了一个stock对象,将其初始化参数提供的值,并将该对象的地址赋值给postcat指针。在这种情况下,对象没有名称,但可以通过指针来对这个对象进行管理。
***注意:***构造函数不同于其他类方法,一般来说,通过对象来调用方法:

stock1.show();

但无法通过对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的。因此构造函数被用来创建对象,而不能通过对象来调用。
1.3 默认构造函数
默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。也就是说,它是适用于下面这种声明的构造函数:

stock flu_cat;

这条语句惯用的原因在于,如果没有提供任何构造函数,则c++将自动提供默认构造函数。它是默认构造函数的隐式版本。对于stock类来说,默认构造函数可能如下:

stock::stock(){ }

因此将创建flu_cat 对象,但不初始化其成员,这和下面的语句创建x,但没有给它提供值一样:

int x;

默认构造函数没有参数,因为声明中不包含值。
***注意:***当且仅当没有定义任何构造函数时,编译器才会提供默认函数构造函数。为类定义了构造函数以后,就必须手动提供默认的构造函数,否则像上面的声明就会出错。
下面提供两种定义默认构造函数的方式:
第一种:给已有的构造函数的所有参数提供默认值:

stock(const string&co="error",int n=0;double pr=0.0);

另一种方式是通过函数重载来定义另一个构造函数——一个没有参数的构造函数:

stock();

注意:两种方法不可同时使用。
实际上,通常在初始化所有对象时,以确保所有成员一开始就有合理的值。因此,用户定义的默认构造函数通常给所有的成员提供隐式初始值:

stock ::stock()
{
	company="no name";
	shares=0;
	share_val=0.0;
	total_val=0.0;
	}

在使用上述任意一种方法创建了默认构造函数后,便可以声明对象变量,而不对他们进行显示初始化:

stock first;
stock first=stock();
stock *prelief=new stock;

然而,不要被非默认构造函数的隐式形式所误导:

stock first("concrete cc");//1
stock second();//2
stock third;//3

第一个声明调用非默认构造函数,即接受参数的构造函数;
第二个声明指出,second是一个返回stock对象的函数;
第三个合理

2.1析构函数
构造函数构建完函数过后,程序负责跟踪该对象,直到其过期为止,对象过期时,程序将自动调用析构函数,来完成清理工作。
如:如果构造函数使用new来分配内存,则析构函数使用delete来释放内存。
本文所用的stock类中并没有使用new,所以析构函数并没有所需要的完成的任务,在这种情况下,只需要让编译器生成一个什么都不需要做的隐式析构函数即可。
析构函数的名称比较特殊:在类名前加上。因此,stock类的析构函数为stock()。另外,和构造函数一样,析构函数也没有返回值和声明类型。与构造函数不同的是,析构函数没有参数,所以stock类的析构函数原型如下:

~stock();

由于stock类的析构函数不承担任何重要的工作,因此如下构造

stock::~stock
{
}

2.1.1析构函数何时被调用
1.静态存储类对象,则其析构函数将在程序结束时自动调用
2.自动存储类对象,将在程序执行完代码块时自动调用
3如果对象通过new调用时,当使用delete来释放内存时,析构函数自动调用。
4.临时对象,结束对该对象的使用时自动调用析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停---

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值