类的构造函数和析构函数
构造函数
常规的初始化语法不适用类的初始化
例如:
int a = 10;//整型的初始化
struct thing
{
char *str;
int m;
};
//结构体初始化
struct thing t1 = {"test",666};
class Test
{
private:
int a;
int b;
public:
};
Test t1 = {22,33};//编译错误
不能像结构体一样初始化Test对象的原因是数据部分的访问状态是私有的,这意味着程序不能直接访问数据成员。
如果将数据成员成为公有,而不是私有,就可以像刚才那样初始化类对象,但使数据成为公有的违背了类的一个主要初衷:数据隐藏。
一般来说,最好是在创建对象时对它进行初始化。
声明构造函数
Stock(const std::string & co,long n = 0,double pr = 0.0);//设置默认值
定义构造函数
//构造函数,没有返回值
Stock::Stock(const std::string & co,long n,double pr)
{
company = co;
if(n<0)
{
std::cout << "Number of shares can't be nagative;"
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
使用构造函数
Stock food = Stock("World Cabbage",250,1.25);//显示地调用
Stock food("World Cabbage",250,1.25);//隐式地调用
Stock *p1 = new Stock("games",18,19.0);//new动态分配内存
构造函数的使用方式不同于其他类方法,一般来说,使用对象来调用方法
food.show();
但无法使用对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的,因此构造函数被用来创建对象,而不能通过对象来调用。
默认构造函数
Stock fluffy_the_cat;
如果没有提供任何构造函数,则C++将自动提供默认构造函数。它是默认构造函数的隐式版本。默认构造函数没有参数,因为声明中不包含值。
Stock::Stock(){ }
注意的是:
当没有定义任何构造函数时,编译器才会提供默认构造函数,为类定义了构造函数后,就必须为它提供默认构造函数,否则将出错。
#ifndef STOCK00_H_
#define STOCK00_H_
#include <string>
class Stock
{
private://可不写,默认是private
std::string company;
long shares;
double share_val;
double total_val;
void set_tot(){total_val = shares * share_val;}//内联函数
public:
Stock(const std::string & co,long n = 0,double pr = 0.0);//设置默认值
Stock(){}//默认构造函数
};
#endif
#include<iostream>
#include"stock00.h"
//构造函数,没有返回值
Stock::Stock(const std::string & co,long n,double pr)
{
company = co;
if(n<0)
{
std::cout << "Number of shares can't be nagative;"
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
析构函数
用构造函数创建对象后,程序负责跟踪该对象,直到过期为止。对象过期时,程序将自动调用一个特殊的成员函数,即析构函数。
析构函数的声明
在类名前加上~
~Stock();
析构函数的定义
//析构函数
Stock::~Stock()
{
using std::cout;
cout << "Bye" << "!\n";
}
改进Stock类(加入构造函数和析构函数)
#ifndef STOCK00_H_
#define STOCK00_H_
#include <string>
class Stock
{
private://可不写,默认是private
std::string company;
long shares;
double share_val;
double total_val;
void set_tot(){total_val = shares * share_val;}//内联函数
public:
Stock(const std::string & co,long n = 0,double pr = 0.0);//设置默认值
Stock(){}//默认构造函数
~Stock();//析构函数
void acquire(const std::string & co,long n,double pr);
void buy(long num,double price);
void sell(long num,double price);
void update(double price);
void show();
};
#endif
#include<iostream>
#include"stock00.h"
//定义成员函数时,使用作用域解析运算符::来标识函数所属的类
//构造函数,没有返回值
Stock::Stock(const std::string & co,long n,double pr)
{
company = co;
if(n<0)
{
std::cout << "Number of shares can't be nagative;"
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
//析构函数
Stock::~Stock()
{
using std::cout;
cout << "Bye, " << company << "!\n";
}
void Stock::acquire(const std::string & co,long n,double pr)
{
company = co;
if(n<0)
{
std::cout << "Number of shares can't be nagative;"
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
void Stock::buy(long num,double price)
{
if(num<0)
{
std::cout << "Number of shares purchased can't be negative. "
<< "Transaction is aborted.\n";
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num,double price)
{
using std::cout;
if (num<0)
{
cout << "Number of shares sold can't be negative. "
<< "Transaction is aborted.\n";
}
else if(num > shares)
{
cout << "You can't sell more than you have! "
<< "Transaction is aborted.\n";
}
else
{
shares -= num;
share_val = price;
set_tot();
}
}
void Stock::update(double price)
{
share_val = price;
set_tot();
}
void Stock::show()
{
using std::cout;
cout << "Company: " << company << "Shares: "
<< shares << '\n' << "Share Price: $"
<< share_val << " Total Worth: $"
<< total_val << '\n';
}
#include<iostream>
#include"stock00.h"
int main()
{
/*
food.Sock(); 不能使用对象来调用构造函数
*/
#if 0
Stock food = Stock("World Cabbage",250,1.25);//显示地调用
Stock food("World Cabbage",250,1.25);//隐式地调用
food.show();
#endif
#if 1
/*
当没有定义任何构造函数时,编译器才会提供默认构造函数;假如定义了构造函数,没有定义默认构造函数,则 "Stock fluffy_the_cat"
这样的形式创建对象时会出错,默认构造函数是形参为空的函数,例如"Stock(){}"
*/
Stock fluffy_the_cat;
fluffy_the_cat.acquire("NanoSmart",20,12.50);
fluffy_the_cat.show();
fluffy_the_cat.buy(15,18.125);
fluffy_the_cat.show();
fluffy_the_cat.sell(400,20.00);
fluffy_the_cat.show();
fluffy_the_cat.buy(300000,40.125);
fluffy_the_cat.show();
fluffy_the_cat.sell(300000,0.125);
fluffy_the_cat.show();
#endif
return 0;
}