c++ primer chapter one (a Sales_item example) 理解操作符重载

很久之前就有写博客的想法,久久没有行动,今天终于写出我的第一篇博客了,哈哈。在阅读了好多牛人的博客后,让我受益匪浅,这也是我要写博客的主要原因之一,书写能让人更好的思考,更能挖掘出问题的本质,呵呵,你觉着呢?

  闲话少说了,步入正题吧,最近在看C++Primer,我学计算机有5年多了(目前还在读书,悲哀,呵呵),对c++也算有一定理解了,可看了第一章后才发现c++真的是门博大精深的语言,很多东西,不理解本质,是很难完全掌握的。还好C++Primer给了我们去深入理解它的机会,经典书籍啊,第一章中有个例子我觉着值得研究,就是卖书记录那个类的定义和实现(Sales_item class),卖书记录类的定义中包括三个私有成员书目的编码 isbn , 此记录中卖出的数目 units_sold ,  总收入 revenue 。先把代码拷过来了,下面是Sales_item.h中的代码,其中定义了各种操作符重载函数,使你能够像使用build-in type 的对象一样去使用Sales_item类型的对象。本文主要就是要探讨一下它对操作符重载的实现方式,大家先看下代码吧

#include <iostream>
#include <string>

class Sales_item {
friend bool operator==(const Sales_item&, const Sales_item&);
public:
    // added constructors to initialize from a string or an istream
    Sales_item(const std::string &book):
              isbn(book), units_sold(0), revenue(0.0) { }
    Sales_item(std::istream &is) { is >> *this; }
    friend std::istream& operator>>(std::istream&, Sales_item&);
    friend std::ostream& operator<<(std::ostream&, const Sales_item&);
public:
    // operations on Sales_item objects
    // member binary operator: left-hand operand bound to implicit this pointer
    Sales_item& operator+=(const Sales_item&);
public:
    // operations on Sales_item objects
    double avg_price() const;
    bool same_isbn(const Sales_item &rhs) const
        { return isbn == rhs.isbn; }
    // default constructor needed to initialize members of built-in type
    Sales_item(): units_sold(0), revenue(0.0) { }
// private members as before
private:
    std::string isbn;
    unsigned units_sold;
    double revenue;

};


// nonmember binary operator: must declare a parameter for each operand
Sales_item operator+(const Sales_item&, const Sales_item&);

inline bool
operator==(const Sales_item &lhs, const Sales_item &rhs)
{
    // must be made a friend of Sales_item
    return lhs.units_sold == rhs.units_sold &&
           lhs.revenue == rhs.revenue &&
    lhs.same_isbn(rhs);
}

inline bool
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
    return !(lhs == rhs); // != defined in terms of operator==
}

using std::istream; using std::ostream;

// assumes that both objects refer to the same isbn
inline
Sales_item& Sales_item::operator+=(const Sales_item& rhs)
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

// assumes that both objects refer to the same isbn
inline
Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
    Sales_item ret(lhs);  // copy lhs into a local object that we'll return*****************(1)
    ret += rhs;           // add in the contents of rhs
    return ret;           // return ret by value
}

inline
istream&
operator>>(istream& in, Sales_item& s)
{
    double price;
    in >> s.isbn >> s.units_sold >> price;
    // check that the inputs succeeded
    if (in)//****************************************************************(2)
        s.revenue = s.units_sold * price;
    else
        s = Sales_item();  // input failed: reset object to default state*******************(3)
    return in;
}

inline
ostream&
operator<<(ostream& out, const Sales_item& s)
{
    out << s.isbn << "/t" << s.units_sold << "/t"
        << s.revenue << "/t" <<  s.avg_price();
    return out;
}

inline
double Sales_item::avg_price() const
{
    if (units_sold)
        return revenue/units_sold;
    else
        return 0;
}
 让我们一起来分析分析它吧,该文件一共定义了六个操作符重载函数,类中声明了4个 ==  +=   <<   >> ,类外面声明并定义了两个 != 和 +,他们的实现方式是有区别的,你看出来了吗?我觉着可以将他们分为以下三类。

第一类:通过friend关键字在类中声明该操作符重载函数为此类的友元,从而可以在函数体中访问类的私有成员进而实现相应操作符的功能,在这种定义方式中操作符所需要的操作数应该与函数参数相对应来定义(nonmember binary operator: must declare a parameter for each operand),即对二元操作符来说重载函数就应该有两个函数参数,这与第二种实现方式是完全不一样的,通过此种实现方式的操作符有三个 == <<  >>,我觉着其中<<  >> 这两个操作符只能通过这种方式来实现,因为他们的左操作数并不是Sales_item类型的,重载函数无法定义成类的成员函数。==就不一样了,它的左操作数正是Sales_item类型。

第二类:将重载函数定义为类的成员函数,既然是成员函数了,当然可以访问私有成员了,操作符重载函数的功能也就实现了。这种实现方式操作符的左操作数并不作为参数传给成员函数,而是可以通过this直接访问左操作数,更确切的说是编译器通过左操作数调用的成员函数,当然不用传了,你说对吧?这样的话二元操作符的重载函数就只有一个函数参数了,与右操作数对应(member binary operator: left-hand operand bound to implicit this pointer)。+=操作符用的就是这种实现方式。

第三类:这类指的是!= 和 + 两个操作符重载函数,他们被单独搞出一类是因为他们不需要访问类的私有成员,因此他们不需要声明成类的友元函数,直接定义就好了,当然他们也可以定义成类的成员函数,左操作数都是Sales_item类型啊,对吧。

 

我觉得代码中还有几个地方值得注意一下(代码中已标出(1) (2) (3)),下面简单解释下:

1.Sales_item ret(lhs);  // copy lhs into a local object that we'll return 应该是调用了编译器为该类加上的默认拷贝构造函数(浅拷贝)

2.if (in) 其中in是istream类型的对象,之所以可以这吗写,应该是istream类型中定义了强制类型转换操作符重载函数 boolean()

3.s = Sales_item();  // input failed: reset object to default state 我理解这句话应该是先定义了一个匿名对象(Sales_item类型),之后调用拷贝构造函数,拷贝到s中。不知道这吗解释对不对?

 

哈哈,终于写完了,第一次写,难免语句生硬,大家凑合着看吧,有什么技术上的错误,欢迎指出。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《C Primer》第5版是一本C语言编程的经典教材,编写了三位C语言领域的专家,清晰地、基础地、全面地介绍了C语言的基础知识和高级编程技巧。 本书的章节安排很合理,首先介绍了C语言的概述和基础知识,然后深入讲解了程序结构、数据类型、函数、数组、指针、字符串、结构体等内容,最后详细探究了C语言程序调试、内存管理、文件处理等高级应用技巧。配合书中的大量实例和习题,读者可以逐步壮大自己C语言的能力和经验。 更值得一提的是,本书既可供中高级程序员学习参考,又可作为初学者的首选入门教材,对于不同程度的读者,本书都能起到很好的指导作用。同时,书中涉及了一些现代化的编程技术和工具,例如C++语言的特性、程序设计的实践方法、线程和多线程编程等,这对于对C语言开发有更高追求的读者也是非常有益的。 总的来说,《C Primer》第5版是一本基础全面、引人入胜、适合不同学习者的优秀C语言教材,彰显了编写者的深厚学术功底和丰富的实践经验。相信任何希望深入理解C语言和提高编程能力的人都应该读一读它。 ### 回答2: 《C Primer》是一本经典的C语言教材,已经出到第5版,本文将从以下几个方面对这本书进行回答。 首先,本书的内容十分系统和全面,从C语言基础概念的介绍开始,一步步地引导读者逐渐掌握C语言的语法和编程技巧,涵盖了C语言的各个方面,包括数据类型、运算符、数组、指针、结构体、函数、文件操作、动态内存管理等。 其次,这本书深入浅出,充满了很多实际的例子和练习题,让读者能够更好地理解和掌握C语言的知识。此外,书中也有很多注意事项和技巧提示,帮助读者避免一些常见的错误和陷阱。 再次,本书具有很强的实用性,所有涉及的知识都有大量的编程实例,读者可以通过实际动手编写程序来巩固知识和提高技能。此外,书中也有很多高级的话题和扩展阅读材料,对于想深入了解C语言的读者来说,这些内容也是值得一看的。 最后,需要注意的是,由于C语言的发展和变化,本书所涉及的一些细节和用法可能已经有所过时,所以在实际编程中还需要结合具体的实践和查阅相关文献来进行处理。不过无论如何,《C Primer》仍是一本不可多得的优秀C语言教材,对于初学者和中级开发者来说都是一本不可多得的参考书籍。 ### 回答3: 《C Primer》是 C 语言的入门经典教材之一,在第五版中进行了全面的更新和修订,以反映当前的 C 语言标准和最佳编程实践。作为一本经典教材,它适用于既没有 C 编程经验也没有计算机科学背景的初学者,同时也适合作为专业程序员的参考工具书。本书旨在帮助初学者全面掌握 C 语言的基本概念、核心语法、程序化思考和最佳编程实践,以及深入理解计算机的原理和机制。 本书内容分为两部分:基础和高级篇。基础篇从 C 语言的语法和控制流开始,介绍了各种基本类型、数组、指针、结构体和函数等,同时也介绍了 C 语言的输入输出和文件处理,以及如何进行调试和错误处理。高级篇则更深入一些,包括了动态内存管理、多线程编程、位运算、预编译器、C11 及 C17 标准等方面的内容。在这一部分中,读者可以学会如何构建更加复杂的程序和模块,同时了解如何使用 C 语言的高级特性。 本书有以下几个特点: 1、全面而深入的讲解:本书对 C 语言的各个方面进行了详细而全面的讲解,同时也深入介绍了计算机的底层机制和编程实践。 2、严谨和实用的教学方法:本书的教学方法既严谨又实用,通过大量的代码示例和练习,读者可以快速掌握 C 语言的核心概念和编程技巧。 3、与时俱进的内容:本书对 C 语言的最新标准和编程实践进行了收录,确保读者学到的是最新、最优秀的编程实践。 总之,《C Primer》是一本非常优秀的 C 语言教材,无论是初学者还是专业程序员都可以从中受益。如果你希望快速掌握 C 语言并用它来进行高效的编程工作,那么这本书是你不可或缺的工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值