构造器与析构器

//stock10.h
#ifndef STOCK10_H
#define STOCK10_H
#include 


class Stock
{
public:
    Stock();
    Stock(const std::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();
private:
    std::string company;
    long shares;
    double share_val;
    double total_val;
    void set_tot()
    {
        total_val = shares * share_val;
    }
};

#endif // STOCK10_H
//stock10.cpp
#include "stock10.h"
#include 

Stock::Stock()
{
    std::cout<<"Default constructor called\n";
    company = "no name";
    shares = 0;
    share_val = 0.0;
    total_val = 0.0;
}

Stock::Stock(const std::string & co, long n, double pr)
{
    std::cout<<"Constructor using "<< co <<" called\n";
    company = co;
    if(n < 0)
    {
        std::cout << "Number of shares can't be negative "
        < shares)
    {
        cout<<"You can't sell more than you have "
           <<"Transaction is aborted.\n";
    }
    else
    {
        shares -= num;
        share_val = price;
        set_tot();
    }
}

void Stock::show()
{
    using std::cout;
    using std::ios_base;
    ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);
    std::streamsize prec = cout.precision(3);

    cout<<"Company:"<
#include 
#include "stock10.h"

using namespace std;


int main()
{

    using std::cout;
    cout<<"Using constructor to creat new object\n";
    Stock stock1("NanpSmart", 12, 20.0);
    stock1.show();
    Stock stock2 = Stock("Boffo Objects", 2, 2.0);
    stock2.show();

    cout<<"Assigning stock1 to stock2: \n";
    stock2 = stock1;
    cout<<"Listing stock1 and stock2:\n";
    stock1.show();
    stock2.show();

    cout<<"Using a constructor to reset an object\n";
    cout<<"*********************\n";
    stock1 = Stock("Nifty Foods", 10, 50.0);//stock1对象已经存在,因此这条语句不是对stock1进行初始化,而是将新值赋给它。这是通过让构造程序创建一个新的、临时的变量,然后将其内容复制给stock1来实现。随后程序调用析构函数,以删除该临时对象
    cout<<"********************\n";
    cout<<"Revised stock1:\n";
    stock1.show();
    cout<<"Done\n";
    return 0;
}

一、const成员函数

const Stock land = Stock("kludgehorn properties");
land.show();

上述代码的第二行是无法通过的,因为show()的代码无法保证调用对象不被修改,解决方法:

void show() const

以这种方法定义的类函数被称为const成员函数。就像应该尽可能将const引用和指针做函数形参一样,只要类方法不修改调用对象,就应该将其声明为const。

二、this指针

目前,每个类成员都只涉及一个对象,即调用它的对象。但有的时候方法可能涉及到两个对象,在这种情况下需要使用C++的this指针。

假设现在需要完成如下功能,让程序查看一系列股票,找到价格最高的那一只。

const Stock &topval(const Stock &s) const

该函数隐式的访问一个对象,而显式的访问另一个对象,并返回其中一个对象的引用。括号中的const表明,该函数不会修改被显式地访问的对象;而括号后的const表明,该函数不会修改被隐式访问的对象。

假设要对Stock对象stock1和stock2进行比较,并将其中股票总价的那一个赋值给top对象,则有:

top = stock1.topval(stock2);
top = stock2.topval(stock1);

第一种方法隐式的访问stock1,而显式的访问stock2;方法二同理。无论使用哪一种方法,都将对这两个对象进行比较,并返回股价总值较高的那一个对象。

同时,还要注意topval()的实现,他将引发一个小问题。下面的部分强调了这个问题:

const Stock& Stock::topval(const Stock &s) const
{
    if(s.total_val > total_val)
    {
        return s;
    }
    else
    {
        return ???;
    }
}

问题在于,如何称呼这个对象?如果调用stock.topval(stock2),则s是stock2的引用,但stock1没有别名。

C++的解决方法是:使用被称为this的特殊指针。this指针指向用来调用成员函数的对象(this作为隐藏参数传递给方法)。这样,函数调用stock.topval(stock2)将this指针设置为stock1对象的地址,使得这个指针可以用topval方法。一般来说,所有的类方法都将this指针设置为调用它的对象的地址。确实,topval()中的total_val只不过是this->total_val的简写。

总结:每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以使用表达式*this。this是对象的地址,而对象本身是*this。

const Stock& Stock::topval(const Stock &s) const
{
    if(s.total_val > total_val)
    {
        return s;
    }
    else
    {
        return *this;
    }
}

 

你可能感兴趣的:(C++)