《C++ Primer Plus》第十章 对象和类-this指针和对象数组

1.1 thish指针

        上两篇文章每个类成员函数都只涉及到一个对象,即调用它的对象,但有时候需要涉及到两个对象,this指针就发挥重要作用。

例如:为了让程序查看一系列股票,找到价格最高的那一支,可以定义一个成员函数,让它查看两个Stock对象,并返回股价较高的那个对象的引用。

        1.1.1 Q1:如何将两个要比较的对象提供给成员函数?

假设将该方法命名为topval( ),则函数调用stock1.topval( )将访问stock1对象的数据,而stock2.topval( )将访问stock2对象的数据。如果希望该方法读两个对象进行比较,则必须将第二个对象作为参数传递给他,效率第一原则,可以按“引用”来传递参数,即topval( )方法使用一个类型为 const Stock&的参数。

        1.1.2 Q2: 如何将方法的答案传回给调用程序?

让方法返回一个引用,该引用指向股价总值较高的对象。

Const Stock & topval( const Stock & s ) const;

分析上述函数:

  1. 该函数隐式地访问了一个对象,而显式地访问另外一个对象,并返回其中一个对象的引用;
  2. 括号中的const表明,该函数不会修改被显式地访问的对象;
  3. 括号后的const表明,该函数不会修改被隐式地访问的对象;
  4. 该函数返回了两个const对象之一的引用,因此返回类型也应为const引用。 

如果用关系操作符 > 来比较这两个对象,将更为清晰:

const Stock & Stock::topval (const Stock & s) const{

        if (s.total_val > total_val)

        return s;

        else

        return ???}

        s.total_val 是作为参数传递的对象的总值(显式), total_val是用来调用该方法的对象的总值(隐式);如果s.total_val大于total_val,则函数返回s,否则将返回调用该方法的对象。

        1.1.3 Q:这个对象究竟怎么表现?

        如果调用stock1.topval(stock2),则s是stock2的引用(即别名),但stock1没有别名。C++提供解决这个问题的方法,使用this特殊指针。

        This指针指向用来调用成员函数的对象。函数调用stock1.topval(stock2)将this设置为stock1对象的地址,stock2.topval(stock1),将this设置为stock2对象的地址.所有类方法都将this指针设置为调用它的对象的地址,通过指针来访问结构成员,也适用于类成员this->total_val.

1.2 this指针详解

        每个成员函数(包括构造函数和析构函数)都有一个this指针,this指针指向调用对象,如果方法要引用整个调用对象,则可以用*this;当要返回的并不是this,因为this是对象的地址,而是对象本身,即*this(将接触引用操作符*用于指针,将得到指针指向的值。图为this调用两个对象:

1.3 程序实现

        1.3.1 stock20.h文件:

#ifndef __STOCK20_H__
#define __STOCK20_H__

#include <string>
//类只作函数的声明
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 std::string &co = "Error", long n= 0, double pr =0.0); //默认构造函数
                Stock(const std::string &co , long n, double pr);//获取哪家公司的股票,买多少支股票,每支股票价格
                ~Stock();
                void buy(long num , double price);//购买股票的数量和价格
                void sell(long num , double price);//出售股票的数量和价格
                void update(double price);//更新股票的价格
                void show() const;//显示股票当前信息

                //函数返回值是const 类型的引用,函数名为topval,不允许通过this指针隐式访问对象
                const Stock &topval(const Stock &s) const;

};
#endif 

        1.3.2 stock20.cpp文件

#include <iostream>
#include "stock20.h"

Stock::Stock() //默认构造函数只能有1个
{
        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)
        {       //不能购买负的股票
                std::cout << "Number of shares can't be negative; "<< company << "shares set to be 0."<<std::endl;
                shares = 0;
        }
        else 
                shares = n;
        share_val = pr;
        set_tot();
}

Stock::~Stock()
{
        std::cout << "Bye" << company <<"\n";
}


void Stock::buy( long num , double price )
{
         if(num < 0)
        {       //不能购买负的股票
                std::cout << "Number of shares can't be negative,tuansaction is aborted "<<std::endl;
        }
        else 
        {
               shares += num;
                share_val = price;
                set_tot();
        }
}

void Stock::sell(long num, double price)
{
        using std::cout;
          if(num < 0)
         {       //不能卖负的股票
                std::cout << "Number of shares can't be negative,tuansaction is aborted "<<std::endl;
         }
        else  if (num >shares) //卖出股票的数目不能超出当前手中的数目
        {
                cout << "You can't sell more than you have! Transanction is aborted"<<std::endl;
        }
        else
        {
                shares -= num;
                share_val = price; //更新当前股票价格
                set_tot();//计算当前资产
        }
}

void Stock::update(double price) //更新当前股票的价格
 {
        share_val = price;
        set_tot();//更新当前的总资产
 }
void Stock::show() const
{
        std::cout << "Company: " << company << std::endl;
        std::cout << "Share: " << shares << std::endl;
        std::cout << "Share price "<< share_val << std::endl;   
        std::cout << "Total worth: "<< total_val << std::endl;
}

const Stock &Stock::topval(const Stock &s) const  //不希望this指针改变对象的值,返回隐式或显式对象
{
        if(s.total_val > total_val)  //total_val == this ->total_val
                return s;
        else
                return *this; //取值运算符,返回this指针指向的对象的内容
}

        1.3.3 usestock20.cpp文件

#include <iostream>
#include "stock20.h"

int main (void)
{
        using std::cout;   
        Stock stock1("Nanosmart", 12, 20.0); //隐式调用构造函数
        stock1.show();

        Stock stock2 = Stock("Boffo objects" , 2, 2.0);//显式调用构造函数
        stock2.show();//运用类的对象调用构造函数

        //比较两支股票谁总额比较大
        Stock top = stock1.topval(stock2);  //利用stock1类的对象来访问topval,与stock2进行比较
        cout << "\nNow show the top val:\n";
        top.show();

        return 0;
}

        1.3.4 程序运行结果

 

2.1 对象数组

        用户通常要创建同一个类的多个对象,可以创建独立对象变量,但创建对象数组将更为合适。

        1.Stock mystuff[ 4 ],其中每个元素都是Stock的对象

        mystuff[ 0 ].update();

        mystuff[ 3 ].show();

        2.用构造函数初始化数组元素

        Const int STK = 4;

         Stock stocks[STKS] = {

         Stock("NanoSmart", 12, 20.0),

         Stock("Boffo Objects", 200, 2.0),

         Stock("Mono", 130, 3.25),

         Stock("Fleep", 60, 6.5)

};

 使用标准格式对数组进行初始化:用括号括齐,以逗号分隔的值列表,每次构造函数调用表示一个值,如果类包含多个构造函数,则可以对不同的元素使用不同的构造函数

        const int STK = 10 ;

        Stock stocks[STKS] = {

                         Stock("NanoSmart", 12, 20.0),

                        Stock( ),

                         Stock("Boffo Objects", 200, 2.0),

    上述代码使用Stock(const char * co, int n, double pr)来初始化stock[0]和stock[2],使用Stock()构造函数初始化stock[1 ],由于该声明只初始化了数组的部分元素,因此余下的元素将使用默认构造函数进行初始化。

初始化对象数组的方案:

  1. 使用默认构造函数创建数组元素
  2. 花括号中的构造函数将创建临时对象
  3. 临时对象的内容赋值到相应的元素中

因此,要创建类对象数组,则这个类必须要有默认构造函数

2.2 代码实现(更改的主函数文件,其余函数文件同上)

#include <iostream>
#include "stock20.h"

const int STKS = 4;

int main(void)
{
        Stock stocks[STKS] = {
         Stock("NanoSmart", 12, 20.0),
         Stock("Boffo Objects", 200, 2.0),
         Stock("Mono", 130, 3.25),
         Stock("Fleep", 60, 6.5)
};
        std::cout << "Stock holding:\n\n";
        int st;
        for(st = 0; st < STKS; st++)
                stocks[st].show();    //访问每一个类的对象
        const Stock *top = &stocks[0]; //取出对象的指针
        for(st = 1; st< STKS; st++)
         //top指针指向的对象和topval函数对象进行比较
        //要保证类型匹配,处理完毕后,取出最大股票类的对象地址传递给类的指针
          top  =&top->topval(stocks[st]);
        std::cout << "\nMost valuable holding:\n";
        top->show(); //指针对象访问成员函数
        return 0;
}

2.3 运行结果

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值