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.临时对象,结束对该对象的使用时自动调用析构函数。