C++ 类(二)- 构造函数和析构函数

int years = 2001;
struct thing
{
    char *ptr;
    int m;
};
thing amabob = {"wodget", 12};    // valid intialization
Stock hot = {"Sukie's Autosm, Inc.", 200, 50.25}; // No! compiler error

C++ 不能像初始化 years, amabob一样,初始化hot。原因是数据隐藏:数据部分的访问是私有的。因此,C++提供了一类特殊的成员函数-类构造函数,专门用于构造新对象,将值赋给它们的数据成员。

1. 声明和定义构造函数

构造函数的原型和函数名称与类名相同,虽然没有返回值,但没有声明为void类型。实际上,构造函数没有声明类型。

 1 // construct definition
 2 Stock::Stock(const string &co, long n, double pr)
 3 {
 4    company = co;
 5    if(n<0)
 6    {
 7        std::cerr << "Number of shares can't be negative; "
 8                      << company << " shares set to be 0.\n";
 9    }
10    else 
11        shares = n;
12    share_val = pr;
13    set_tot();
14 }

程序声明对象时,将自动调用构造函数。

2. 使用构造函数

(1)显式构造函数

1 Stock food = Stock("Word Cabbage", 250, 1.25);

(2)隐式构造函数

1 Stock garment("Furry Mason", 50, 2.5);

(3)new 动态分配内存,创建对象

1 Stock *pstock = new Stock("Electroshock Games", 18, 19.0);

这条语句创建一个Stock对象,将其初始化为参数提供的值,并将该对象的地址赋给 pstock 指针。在这种情况下,对象没有名称,但可以使用指针来管理该对象。

3. 默认构造函数

默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。也就是说,它是用于下面这种声明的构造函数

Stock fluffy_the_cat;  // uses the default constructor

这条语句合法的原因在于,如果没有提供任何构造函数,C++将提供默认构造函数。它是默认构造函数的隐式版本,不做任何工作。对于Stock类来说,默认构造函数可能如下:

1 Stock::Stock(){}

【注】当且仅当没有定义任何构造函数时,编译器才会提供构造函数。为类定义类构造函数,程序员必须为它提供默认构造函数。如果提供类非默认构造函数(如 Stock::Stock(const char *co, int n, double pr)), 但没有提供默认构造函数,则下面的声明将出错

class Stock
{
    char *company;
    int shares;
    double price;
public:    
    Stock(const char* co, int n, double pr);
};
// 编译器报错
Stock::Stock(const char* co, int n, double pr)
{
    company = cor;
    shares = n;
    price =pr;
}

下面是正确的

 1  class Stock
 2  {
 3     char *company;
 4     int shares;
 5     double prices; 
 6 public:
 7     Stock(){};
 8     Stock(const char* co, int n, double pr);
 9 };
10  
11 Stock::Stock(){}
12 Stock::Stock(const char* co, int n, double pr)
13 {
14     company = co;
15     shares = n;
16     price = pr;
17 }                                                                                        

4. 析构函数

~加上类名为析构函数,如

1 Stock::~Stock(){}

【注】

(1)如果创建的对象是static类型的,则其西沟函数将在程序结束时自动被调用

(2)如果对象是通过new创建的,则它将驻留在栈内存或自由存储区中,当使用 delete来释放内存时,其析构函数将自动被调用。如果构造函数使用了 new, 则必须提供使用 delete的函数。

(3)如果对象是临时创建的,程序将在结束时自动调用其析构函数

5. const 成员函数

 1 // stock10.h -- Stock class declaration with constructors, destructor added
 2 #ifndef STOCK10_H_
 3 #define STOCK10_H_
 4 class Stock
 5 {
 6 private:
 7    std::string company; 
 8    long shares; 
 9    double share_val; 
10    double total_val; 
11    void set_tot(){total_val = shares* share_val;}
12 public:
13    // two constructors
14    Stock(); // default constructor
15    Stock(const std::string &co, long n = 0, double pr = 0.0);
16    ~Stock();
17    void buy(long num, double price);
18    void sell(long num, double price);
19    void update(long num, double price);
20    void show();
21 };
22 #endif

以上为Stock类的原始声明, 以下代码将会发生编译器报错

1 const Stock land = Stock("Kludgehorn Properties");
2 land.show(); // 编译器报错

Line2的代码将会发生编译器报错,因为Stock类的原始声明(Stock10.h中的Line 20)的show() 代码不能确保调用对象不被修改

【解决方案】以下列方式成名和定义的类函数被称为 const 成员函数。

1 // stock10.h
2 void show() const; 
3 // stock10.cpp
4 void Stock::show() const {...};

 

posted @ 2021-02-12 20:24  GaoLee  阅读(160)  评论(0)    收藏  举报