[C++ Primer Plus] 类基础知识--使用类

(一) 散知识
1, 不要返回指向局部变量或临时变量的引用。函数在执行完毕后,局部变量和临时变量对象将消失,引用将
指向不存在的数据。

(二) 运算符重载
1, 运算符重载的格式:     
       operator op(argument-list)
其中,op是有效的的C++运算符,不能虚构一个新的符号。
假设存在两个类对象a和b都是A类型,重载运算符 + 之后便可以执行以下操作来求得两个对象之和:

       c = a + b;
在执行的过程中,编译器发现操作数都是A类对象,因此使用相应的运算符函数替换上述运算符:
        c = a.operator+(b);
然后函数将隐式地使用a(因为它调用了方法),而显式地使用b对象(因为它做为参数传递),来计算总和。
可以将两个以上的对象相加:

        d = a + b + c;
程序执行过程如下:
        d = a.operator+(b + c);
        d = a.operator+(b.operator+(c));
        需要记住的是:对于成员重载运算符函数来说,左侧的操作数是调用对象。而对于非成员重载运算符函数来说
运算符表达式左边的操作数对应于运算符函数的第一个参数,运算符右边的操作数对应于运算符函数的第二个
参数。

2, 重载限制
        第一,重载的运算符不必是成员函数,但必须至少有一个操作数是用户定义的类型,这将防止用户为标准
类型重载运算符。因此,不能将减法运算符(-)重载为计算两个double值的和,而不是他们的差;
        第二,使用运算符时不能违反运算符原来的句法规则。如不能将求模运算符(%)重载成使用一个操作数;
同样不能修改运算符的优先级;
        第三,不能创建新的运算符l;
        第四,以下运算符只能通过成员函数进行重载:
        赋值运算符=,函数调用运算符(),下标运算符[],通过指针访问类成员的运算符->。

(三) 友元
        通常,公有类方法提供唯一访问类私有数据的途径,但通过让函数成为类的友元,可以赋予该函数与类
成员函数相同的访问权限。
        对于友元阅读是存在的疑问:
        第一,为什么一定需要友元函数?
        简单的说就是为一个类来访问另一个类的数据成员服务。假如trip是一个Time类,要想使用cout来显示
Time类:

        cout<<trip;
其中第一个左操作数为ostream类对象,右操作数为Time类对象,如果使用一个Time成员函数来重载<<,Time对
象将是左操作数,也就是意味着应该这样使用<<:

        trip<<cout;
此时就需要一个友元函数来解决以上问题,即既不是Time类成员函数又能访问Time类数据成员:
        friend void operator<<(ostram & os, const Time & t); // 友元函数声明
        void operator<<(ostram & os, const Time & t) // 友元函数定义
        {
                ...
        }
      第二,如上的重载函数是否应该同时是Time和ostream类的友元?
         operator<<()函数显式地访问了Time类对象的私有数据,所以operator<<()函数必须是Time类的友元。但
由于它并没有直接访问ostream类对象的私有成员,所有并不一定是ostream类的友元。也就是说,尽管
operator<<()函数访问了Time对象的私有成员,但它始终都将ostream对象作为一个整体使用。

1,创建友元
        创建友元的第一步是将其原型放在类声明中,并在其原型声明前加上关键字 friend :
        friend Time operator*(double m, const Time & t);
该原型意味着两点:
第一,虽然 operator*()函数是在类声明中声明的,但它不是成员函数,因此不能使用成员运算符来调用;
第二,虽然 operator*()函数不是成员函数,但它与成员函数的访问权限相同;
        接下来编写函数定义,如上,因为它不是成员函数,故不需要成员限定符::,另外不要在定义中使用
关键字friend。

(四) 类的自动转换与强制类型转换
1,从某种类型转换为类类型--构造函数
        C++中接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了蓝图。
        假设Stonewt类拥有如下构造函数:

        Stonewt(double lbs);
因此该构造函数能够将double类型的值转换为Stonewt类型,也就是说可以这样编写代码:
        Stonewt myCat;
        myCat = 19.6;
程序将使用构造函数Stonewt(double lbs)来创建一个临时的Stonewt对象,并将19.6作为初始值,随后,采用逐
成员赋值的方式将该临时对象的内容复制到myCat中。这一过程称为隐式转换,因为它为自动进行的,而不需要
显示的强制转换。
        只有接受一个参数的构造函数才能作为转换函数。但如果存在两个及以上参数的构造函数,并且只有一个
参数没有默认值,也可以成为转换函数,如下面的构造函数可以用于转换int:

        Stonewt(int stn, double lbs = 0);
        将构造函数用作自动类型转换函数是一项不错的特性,但C++也提供用于关闭该特性的方法--新增了关键字
explicit,也就是说可以这样声明构造函数:

        explicit Stonewt(double lbs);
这将关闭上面提到的隐式转换,但扔允许显示转换,即显示强制类型转换:
        Stonewt myCat;
        myCat = 19.6; //not allow
        myCat = (Stonewt) 19.6;
2,从类类型转换到某种类型--转换函数
        要将类类型转换为typeName类型,要使用如下形式的转换函数:

        operator typeName();
需注意以下几点:
        第一:转换函数必须是类方法;
        第二:转换函数不能指定返回类型;
        第三:转换函数不能有参数;
例如,转换为double类型的转换函数原型如下:

        operator double();
定义了如上的转换函数就可以使用下面的转换:
        Stonewt wolfe(285.5);
        double host = double(wolfe);  //方式一
        double thinker = (double) wolfe;  //方式二
        double star = wolfe;  //方式三
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值