通常情況下,類的成員函數都只涉及一個對象,即調用它的對象。但有時候方法可能涉及到兩個對象,在這種情況就需要使用到C++的this指針。
class Stock
{
private:
...
double total_val;
...
public:
double total() const {return total_val;}
}
如上述類,total_val為私有成員,外部程序不可以直接訪問該數據成員,只能通過total()方法獲取total_val值。如果要知道哪個Stock對象total_val的值最大,方法一是對象調用total()方法來較total_val值。
另外一種方法就是使用this指針。定義一個成員函數,該函數可以查看兩個Stock對象,并返回total_val值較高對象的引用。擬定成員函數名為topval(),stock1.topval()訪問stock1對象的數據成員;stock2.topval()訪問stock2對象的數據成員。要對兩個對象進行比較,則必須將其中一個對象作為參數,傳遞給成員函數topval(),則topval()的參數類型應為const Stock &(出于效率原因選擇使用引用來傳遞參數)。topval()需要返回total_val值較大的對象,則可以直接返回一個Stock對象的引用。topval()方法的原型如下:
const Stock & topval(const Stock & s)const;
topval()方法隱式的訪問一個對象,顯式地訪問一個對象,并返回其中一個對象的引用。括號中的const表示該函數不會修改被顯式訪問的對象;括號后面的cosnt表明,該函數不會修改被隱式訪問的對象。由于該函數返回了兩個const對象之一的引用,因此返回類型也應使用const修飾。
假設都要對Stock對象stock1和stock2進行比較,將total_val值較大的對象賦值給top對象,可以使用以下兩條語句實現:
top = stock1.topval(stock2);
top = stock2.topval(stock1);
第一種格式:隱式地訪問stock1,顯式地訪問stock2;第二種格式:隱式地訪問stock2,顯式地訪問stock1。無論使用哪一種格式,都會返回total_val值較大的那個對象。
C++中this指針指向用來調用成員函數的對象(this被作為隱藏參數傳遞給方法)。stock1.topval(stock2);語句將this設置為stock1對象的地址。一般來說,類方法都將this指針設置為調用它的對象的地址。topval()中的total_val只不過是this->total_val的簡寫。topval()的實現如下:
const Stock & Stock::topval(const Stock & s)const
{if(s.total_val > total_val)return s;elsereturn *this;
}
特別提醒: 每個成員函數(包括構造函數和析構函數)都有一個this指針。this指針指向調用對象。如果方法需要引用整個調用對象,則可以使用表達式 * this 。在函數的括號后面使用const限定符將this限定為const,這樣就不能使用this來修改對象的值。this是對象的地址,而不是對象本身。* this才是對象本身, * this可以作為調用對象的別名。( * this將解除引用運算符*用于指針,將得到指針指向的值)
示例代碼如下:
1、定義文件stock20.h
//stock20.h--augmented version
#pragma once
#include <string>class Stock
{
private:std::string company;int shares;double share_val;double total_val;void set_tot() { total_val = shares * share_val; }
public:Stock();Stock(const std::string & c0, int 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()const;const Stock& topval(const Stock & s)const;
};
2、實現文件stock20.cpp
//stock20.cpp--augement version
#include "stock20.h"
#include <iostream>
Stock::Stock()
{company = "no name";shares = 0;share_val = 0.0;total_val = 0.0;
}
Stock::Stock(const std::string& co, int n, double pr)
{company = co; if (n < 0){std::cout << "Number of shares can't be negative;"<< company << " shares set to 0.\n";shares = 0;}elseshares = n;share_val = pr;set_tot();
}
Stock::~Stock()
{
}
void Stock::buy(long num, double price)
{if (num < 0){std::cout << "Number of shares purchased can't be nagative." << "Transacyion 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 nagative."<< "Transaction is abored.\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()const
{using std::cout;using std::ios_base;//set format #.###ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);std::streamsize prec = cout.precision(3);cout << "Company: " << company << "Shares: " << shares << '\n';cout << "Shares Price:$" << share_val;//set format to #.##cout.precision(2);cout << " Total Worth:$" << total_val << '\n';//restore original formatcout.setf(orig, ios_base::floatfield);cout.precision(prec);
}
const Stock & Stock::topval(const Stock & s)const
{if (s.total_val > total_val)return s;elsereturn *this;
}
3、使用文件usestok2.cpp
//usestock2.cpp-- using the Stock class
//compilewith stock20.cpp
#include <iostream>
#include "stock20.h"int main()
{Stock kate("NanoSmart", 12, 20.0);kate.show();Stock joe("Fleep Enterprises", 60, 6.5);joe.show();Stock top = kate.topval(joe);std::cout << "\nMost valuable holding:\n";top.show();return 0;
}
代碼運行結果:joe的total_val 值比kate的total_val 值大,故top=joe。