C++中使用类(重载,友元函数,转换函数等)

来源:岁月联盟 编辑:exp 时间:2012-08-14

12点半了。好久没更新C++博文了。把一个章节看完了。接下来说下C++里的操作符重载和以后的内容。时间晚了,可能打字没打好。望大家见谅。
C++中有个operator操作符概念。如果想重载+运算符,那么需要写成operator+()。一般两个数相加是这么调用的:
[cpp] 
a = b+c; == a = b.operator+(c); 

当调用操作符,会有一个隐式的调用。把自己的对象作为操作符的对象。然后显示调用参数c。
重点介绍友元函数。因为重载了运算符后可能出现类似:
[cpp]
a = 1.5 + c; 

此时按照上面的说法。1.5不是一个对象。无法完成操作,这时候就需要友元函数了,其实友元函数就是类的非成员函数,不会隐式的将自身对象也作为参数。
然后贴三段代码,注释写的还算详细。大家可以复制后去运行下看下结果。代码是从C++Primer Plus里抄过来的。
mytime0.h
[cpp] 
#ifndef MYTIME0_H_ 
#define MYTIME0_H_ 
#include <iostream> 
class Time 

private: 
    int hours; 
    int minutes; 
public: 
    Time(); 
    Time(int h, int m = 0); 
    void AddMin(int m); 
    void AddHr(int h); 
    void Reset(int h = 0, int m = 0); 
    Time Sum(const Time & t)const; 
//  接下来时重载+运算符的函数 
    Time operator+(const Time & t)const;     
    void Show()const; 
//  重载-运算符的函数 
    Time operator-(const Time & t)const; 
//  重载*运算符的函数 
    Time operator*(double n)const; 
//  友元函数  类似 a+b 的原型是 a.operator+(b); 所以如果 5*a 则5没有那个重载的函数,这时就不能使用类的成员函数了,需要友元函数来进行操作,类友元函数也就是非成员函数 
    friend Time operator*(double m, const Time & t){return t * m;}  //内联函数,调用该类的成员函数,这里也就是上面那个函数。 
//  友元函数。对于那些非成员重载操作符函数来说,操作符左面的操作数对应函数的第一个参数。类似 c = a+b 类似于 c = operator+(a,b) 
    friend  std::ostream & operator<<(std::ostream & os, const Time & t); 
}; 
 
#endif 
mytime0.cpp
[cpp] 
#include <iostream> 
#include "mytime0.h" 
 
Time::Time() 

    hours = minutes = 0; 

 
Time::Time(int h, int m) 

    hours = h; 
    minutes = m; 

 
void Time::AddMin(int m) 

    minutes += m; 
    hours += minutes / 60; 
    minutes %= 60; 

 
void Time::AddHr(int h) 

    hours += h; 

 
void Time::Reset(int h, int m) 

    hours = h; 
    minutes = m; 

 
Time Time::Sum(const Time & t)const 

    Time sum; 
    sum.minutes = minutes + t.minutes; 
    sum.hours = hours + t.hours + sum.minutes/60; 
    sum.minutes %= 60; 
    return sum; 

 
// 重载加号运算符的版本 
Time Time::operator+(const Time & t)const 

    Time sum; 
    sum.minutes = minutes + t.minutes; 
    sum.hours = hours + t.hours + sum.minutes/60; 
    sum.minutes %= 60; 
    return sum; 

 
Time Time::operator-(const Time & t)const 

    Time diff; 
    int tot1, tot2; 
    tot1 = t.minutes + 60 * t.hours; 
    tot2 = minutes + 60 * hours; 
    diff.minutes = (tot2 - tot1) % 60; 
    diff.hours = (tot2 - tot1) / 60; 
    return diff; 

 
Time Time::operator*(double n)const 

    Time result; 
    long totalminutes = hours * n * 60 + minutes * n; 
    result.hours = totalminutes / 60; 
    result.minutes = totalminutes % 60; 
    return result; 

 
std::ostream & operator<<(std::ostream & os, const Time & t) 

    os << t.hours << "hours, " << t.minutes << " minutes"; 
    return os; 

 
void Time::Show()const 

    std::cout << hours << " hours, " << minutes << " minutes"; 
     

 
//usetime0.cpp 
#include <iostream> 
#include "mytime0.h" 
 
int main() 

    using std::cout; 
    using std::endl; 
    Time planning; 
    Time coding(2, 40); 
    Time fixing(5, 55); 
    Time total; 
 
    cout << "planning time = "; 
    planning.Show(); 
    cout << endl; 
     
    cout << "coding time = "; 
    coding.Show(); 
    cout << endl; 
 
    cout << "fixing time = "; 
    fixing.Show(); 
    cout << endl; 
     
//  total = coding.Sum(fixing); 
//  重载加号运算符的版本 
    total = coding + fixing; 
    cout << "coding + fixing = "; 
    total.Show(); 
    cout << endl; 
 
    Time morefixing(3 ,20); 
    cout << "more fixing time = "; 
    morefixing.Show(); 
    cout << endl; 
    total = morefixing.operator+(total); 
    cout << "morefixing.operator+(total) = "; 
    total.Show(); 
    cout << endl; 
 
    Time aida(3, 35); 
    Time tosca(2, 48); 
    Time temp; 
 
    cout << "Aida and TOsca:/n"; 
    cout << aida <<"; " << tosca << endl; 
    temp = aida + tosca;        // operator+() 
    cout << "Aida + Tosca: " << temp << endl; 
    temp = aida*1.17; 
    cout << "Aida *1.17: " << temp << endl; 
    cout << "10 * Tosca: " << 10 * tosca << endl; 
 
    return 0; 

然后接下来说下类的强制转换和自动转换。

类的自动转换就是,如果你定义了一个只接受一个参数的构造函数,那么在调用构造函数时,如果碰到匹配的参数,直接可以将一个基本类型转换为相应的类类型。其中有几种隐式转换的情况。

1.将某个对象初始化为某个值时。

2.将某个值赋值某个对象。

3.将某值传递给接收某对象参数的函数时。

4.返回值被声明为某个对象的函数返回一个某值时。

5.以上情况中,如果另一个值可以转化为某值时。

使用explicit关键字可以强制使用显式构造函数,可以避免把某值转化为某对象。

如果想进行相反的转换,那么就需要使用C++操作符函数-------转换函数。转换函数是用户自定义的强制类型转换。使用转换函数得注意以下三点:

1.转换函数必须是类方法。

2.转换函数不能指定返回类型。

3.转换函数不能有参数。

同样的,也上三段代码。

stonewt.h
[cpp]
#ifndef STONEWT_H_ 
#define STONEWT_H_ 
class Stonewt 

private: 
    enum{Lbs_per_stn = 14}; 
    int stone; 
    double pds_left; 
    double pounds; 
public: 
    Stonewt(double lbs); 
    Stonewt(int stn, double lbs); 
    Stonewt(); 
    ~Stonewt(); 
    void show_lbs()const; 
    void show_stn()const; 
 
    // 转换函数,将对象转换为内置类型 
    operator int()const; 
    operator double()const; 
}; 
 
#endif 
stonewt.cpp
[cpp] 
#include <iostream> 
using std::cout; 
#include "stonewt.h" 
 
Stonewt::Stonewt(double lbs) 

    stone = int(lbs)/Lbs_per_stn; 
    pds_left = int(lbs)%Lbs_per_stn + lbs - int(lbs); 
    pounds = lbs; 

 
Stonewt::Stonewt(int stn, double lbs) 

    stone = stn; 
    pds_left = lbs; 
    pounds = stn * Lbs_per_stn + lbs; 

 
Stonewt::Stonewt() 

    stone = pounds = pds_left = 0; 

 
Stonewt::~Stonewt() 


 
void Stonewt::show_stn()const 

    cout << stone << " stone." << pds_left << " pounds/n"; 

 
void Stonewt::show_lbs()const 

    cout << pounds << " pounds/n"; 

 
// 转换方法 不带参数,不带返回值类型 
Stonewt::operator int() const 

    return int(pounds+0.5); 

 
Stonewt::operator double() const 

    return pounds;   

stone.cpp
[cpp] 
#include <iostream> 
using std::cout; 
#include "stonewt.h" 
void display(const Stonewt st, int n); 
int main() 

    Stonewt pavarotti = 260;        //调用构造函数,因为260能转化为浮点型 
    Stonewt wolfe(285.7);       //类似Stonewt wolfe = 285.7; 
    Stonewt taft(21,8); 
 
    cout << "The tenor weighted "; 
    pavarotti.show_stn(); 
    cout << "THe detective weighted "; 
    wolfe.show_stn(); 
    cout << "The President weighed "; 
    taft.show_lbs(); 
    pavarotti = 256.8;          //构造函数进行初始化 
    taft = 325;             //和 taft = Stonewt(325);一样 
    cout << "After dinner, the tenor weighed "; 
    pavarotti.show_stn(); 
    cout << "After dinner, the president weighed "; 
    taft.show_lbs(); 
    display(taft, 2); 
    cout << "The wrestler weighted even more./n"; 
    display(422, 2);            //将422转化乘 Stonewt对象 
    cout << "No stone left unearned/n"; 
 
    // 使用转换函数将类对象转化为基本类型 
    Stonewt poppins(9, 28); 
    double p_wt = poppins; 
    cout << "COnvert to double => "; 
    cout << "Poppins: " << p_wt << " pounds./n"; 
    cout << "Convert to int => "; 
    cout << "Poppins: " << int(poppins) << " pounds./n"; 
    return 0; www.2cto.com

 
void display(const Stonewt st, int n) 

    for (int i = 0; i < n; i++) 
    { 
        cout << "Wow! "; 
        st.show_stn(); 
    } 

作者:Paul_wuhaha