1、构造函数
1.1构造函数作用:
C++提供了一个成员函数——构造函数,专门用于构造新对象,将值赋给它们的数据成员。
构造函数是一种特殊的类成员函数,在创建类对象时被调用。构造函数的名称和类型相同,并且没有声明类型。通过函数重载,可以创建多个同名的构造函数,条件是每个函数的额参数列表都不相同。
Stock::Stock()//默认的构造函数
{
company = "No name";
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
Stock::Stock(const std::string & co, long n, double pr)//自定义的构造函数
{
company = co;
if(n<0)
{
cout << "The number of shares can't be negative;"
<< company << " shares set to 0.0\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
1.2、构造函数初始值列表
- 构造函数的初始值列表有时候是必不可少的:第一,如果成员是const或是引用的话,必须将其初始化。第二,当成员属于某种类类型并且该类没有定义默认构造函数时,也必须将这个成员初始化。总之:我们要尽量使用构造函数初始值列表来初始化成员的值。
- 建议:最好令构造函数初始值的顺序与成员声明的顺序保持一致。尽量不要用某些成员初始化其它的成员。
2、析构函数
1、对象过期的时候,会自动调用析构函数。如果构造函数使用了new,则析构函数使用delete来释放内存。析构函数没有返回值和声明类型。
2、由于自动变量是放在栈中,因此最后创建的对象将最先被删除,最先创建的对象将最后被删除。
例子:
#ifndef STOCK00_H_
#define STOCK00_H_
#include <string>
using namespace std;
class Stock
{
private:
std::string company;
long shares;
double share_val;
double total_val;
void set_tot() {total_val = shares * share_val;}
public:
Stock();
Stock(const string & co, long n = 0, double pr = 0.0);
~Stock();
void buy (long num, double price);
void sell (long num, double price);
void update(double price);
void show();
};
#endif
#include "Stock00.h"
#include <iostream>
Stock::Stock()//默认的构造函数
{
company = "No name";
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
Stock::Stock(const std::string & co, long n, double pr)//自定义的构造函数
{
company = co;
if(n<0)
{
cout << "The number of shares can't be negative;"
<< company << " shares set to 0.0\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
Stock::~Stock()//析构函数
{
cout << "Bye " << company << "\n";
}
void Stock::buy(long num, double price)//买股票的函数
{
if(num < 0)
{
cout << "Number of shares can't be negative\n";
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num, double price)//卖股票的函数
{
if(num < 0)
cout << "Number of shares can't be negative\n";
else if(num > shares)
cout << "Number if too more\n";
else
{
shares -= num;
share_val = price;
set_tot();
}
}
void Stock::update(double price)//更新股票价格
{
share_val = price;
set_tot();
}
void Stock::show()//显示对象的内容
{
cout << "Company: " << company
<< " Shares:" << shares;
cout << " Share price: $" << share_val
<< " Total Worth: $" << total_val << endl;
}
#include "Stock00.h"
#include <iostream>
int main()
{
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>cout << "Using constructors to creat new objects\n";
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>Stock stock1;
<span style="white-space:pre"> </span>stock1 = Stock("s1", 12, 12.0);
<span style="white-space:pre"> </span>/*
<span style="white-space:pre"> </span>stock1 = Stock("s1", 12, 12.0);
<span style="white-space:pre"> </span>stock1对象已经存在,这条语句不是对stock1进行初始化,
<span style="white-space:pre"> </span>而是通过让构造函数创建一个新的临时的对象,然后将其内
<span style="white-space:pre"> </span>容复制给stock1。赋值完毕之后,就调用析构函数,删除临时对象,
<span style="white-space:pre"> </span>见运行结果第二行,bye s1。
<span style="white-space:pre"> </span>*/
<span style="white-space:pre"> </span>stock1.show();
<span style="white-space:pre"> </span>Stock stock2 = Stock("s2", 31, 42.0);//显示地调用构造函数
<span style="white-space:pre"> </span>stock2.show();
<span style="white-space:pre"> </span>Stock stock3("s3", 23, 11.0);//隐式地调用析构函数
<span style="white-space:pre"> </span>stock3.show();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>/*
<span style="white-space:pre"> </span>在}之后,对象就该释放内存空间了,此时应该调用析构函数,
<span style="white-space:pre"> </span>见运行结果所示。
<span style="white-space:pre"> </span>*/
<span style="white-space:pre"> </span>cin.get();
<span style="white-space:pre"> </span>return 0;
}
备注:主要是程序中的三种给对象赋值的方式,以及它们的区别。
Stock stock1;
stock1 = Stock("s1", 12, 12.0);
/*
stock1 = Stock("s1", 12, 12.0);
stock1对象已经存在,这条语句不是对stock1进行初始化,
而是通过让构造函数创建一个新的临时的对象,然后将其内
容复制给stock1。赋值完毕之后,就调用析构函数,删除临时对象,
见运行结果第二行,bye s1。
*/
Stock stock2 = Stock("s2", 31, 42.0);//显示地调用构造函数
Stock stock3("s3", 23, 11.0);//隐式地调用析构函数