C++第11章,使用类
2015-06-13 09:47
337 查看
运算符重载
operator+(argument-list)
假设有一个Saleperson类
如果a,b,c都是其对象。
a = b + c;
等价于
a = b.operator+(c)隐式的使用b,显式的使用c
a = b + c + d ;
a = b.operator+( c + d)
a = b.operator+(c.operator+(d));
重载限制:
重载后的运算符的操作数必须有一个是用户自定义的类型,这样可以防止用户为标准类型的操作重载运算符。比如不能把-重载为两个double类型的和。而不是它们的差。
11.3友元
与下面的非成员函数调用匹配:
A = operator*(2.75,B);
该函数的原型如下:
Time operator*(double m,const Time & t);
有一类特殊的非成员函数可以访问类的私有数据,他们被称为友元函数。
C++编程常见错误—cannot have cv-qualifier//不能有CV限定,在C++中CV指const和volatile—1、非成员函数不能有CV限定,2、静态成员函数不能有CV限定
上述对定义进行修改,也可以不使用友元函数,可以将这个友元函数编写为非友元函数
原来的版本显式的访问类的私有成员,所以必须是友元函数,这个版本让成员函数来处理私有值,所以不必是友元函数。
常用的友元: 重载<<运算符
要使Time类知道使用cout,必须使用友元函数。如果使用一个Time成员函数来重载<<,Time对象将是第一个操作数。这意味着必须这样使用<<
trip << cout
但是通过使用友元函数,可以像下面这样重载运算符:
void operator<<(ostream & os,const Time &t){
os << t.hours << “hours ,” << t.minutes << “minutes”;
}
但是返回类型为void,意味着无法cout << x << y 这样使用。
为此可更改为:
ostream& operator<<(ostream & os,const Time &t){
os << t.hours << “hours ,” << t.minutes << “minutes”;
return os;
}
类型转换构造函数:
在C++中,接受一个参数的构造函数,为将类型和该参数相同的值转换为类对象提供了蓝图。
下面的构造函数用于将double类型的值转换为Stonewt类型
Stonewt(double lbs)
Stonewt myCat;
myCat = 19.6;
程序将使用19.6创造一个临时对象并且初始化。随后将赋值给myCat;这一过程称之为隐式转换,因为它是自动进行的。
只有接受一个参数的构造函数才能作为转换函数。但是如果出了第一个参数,其余形参提供了默认值,则可以用于转换。
比如
Stonewt(int a,int b = 0);则可以用于转换int
C++提供了关键字explicit用于关闭这项特性。
explicit Stonewt(int a);
仅仅关闭了隐式类型转换,但是仍然可以进行强制类型转换。
转换函数:
以上将数字转换为Stoewt对象。可以做相反的转换吗?
operator+(argument-list)
假设有一个Saleperson类
如果a,b,c都是其对象。
a = b + c;
等价于
a = b.operator+(c)隐式的使用b,显式的使用c
a = b + c + d ;
a = b.operator+( c + d)
a = b.operator+(c.operator+(d));
重载限制:
重载后的运算符的操作数必须有一个是用户自定义的类型,这样可以防止用户为标准类型的操作重载运算符。比如不能把-重载为两个double类型的和。而不是它们的差。
11.3友元
友元函数
友元类
友元成员函数
通过让函数成为类的友元,可以赋予该函数与类的成员函相同的访问权限。非成员函数不是由对象调用的,它使用的所有值(包括对象)都是显式参数。
A = 2.75 * B;与下面的非成员函数调用匹配:
A = operator*(2.75,B);
该函数的原型如下:
Time operator*(double m,const Time & t);
有一类特殊的非成员函数可以访问类的私有数据,他们被称为友元函数。
C++编程常见错误—cannot have cv-qualifier//不能有CV限定,在C++中CV指const和volatile—1、非成员函数不能有CV限定,2、静态成员函数不能有CV限定
提示:如果要为类重载运算符,并将非类的项作为其第一个操作数,则可以用友元函数来翻转操作数。
#include <iostream> using namespace std; 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 operator+(const Time & t) const; Time operator*(int mult)const; friend Time operator*(int m,const Time & t); void show()const; }; 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::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*(int mult)const{ Time result; result.hours = hours + mult*minutes / 60 ; result.minutes = mult*minutes % 60 ; return result; } void Time::show()const{ std::cout << hours << "hours," << minutes << "minutes"; } Time operator*(int m,const Time & t){ Time result; result.minutes = t.minutes * m % 60; result.hours = t.hours + t.minutes * m / 60; return result; } int main() { /*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 + fixing; cout << "coding.Sum(fixing) = "; total.show(); cout << endl; return 0;*/ Time a(1,35); Time b; b = 2 * a; b.show(); }
上述对定义进行修改,也可以不使用友元函数,可以将这个友元函数编写为非友元函数
Time operator*(int m,const Time & t){ return t * m;//use t.operator*(m); }
原来的版本显式的访问类的私有成员,所以必须是友元函数,这个版本让成员函数来处理私有值,所以不必是友元函数。
常用的友元: 重载<<运算符
要使Time类知道使用cout,必须使用友元函数。如果使用一个Time成员函数来重载<<,Time对象将是第一个操作数。这意味着必须这样使用<<
trip << cout
但是通过使用友元函数,可以像下面这样重载运算符:
void operator<<(ostream & os,const Time &t){
os << t.hours << “hours ,” << t.minutes << “minutes”;
}
但是返回类型为void,意味着无法cout << x << y 这样使用。
为此可更改为:
ostream& operator<<(ostream & os,const Time &t){
os << t.hours << “hours ,” << t.minutes << “minutes”;
return os;
}
代码很短时,应该使用内联函数。inline。一般将定义和声明放在一起。如果分开,则只在声明中使用inline即可。
11.6 类的自动转换和强制类型转换。类型转换构造函数:
在C++中,接受一个参数的构造函数,为将类型和该参数相同的值转换为类对象提供了蓝图。
下面的构造函数用于将double类型的值转换为Stonewt类型
Stonewt(double lbs)
Stonewt myCat;
myCat = 19.6;
程序将使用19.6创造一个临时对象并且初始化。随后将赋值给myCat;这一过程称之为隐式转换,因为它是自动进行的。
只有接受一个参数的构造函数才能作为转换函数。但是如果出了第一个参数,其余形参提供了默认值,则可以用于转换。
比如
Stonewt(int a,int b = 0);则可以用于转换int
C++提供了关键字explicit用于关闭这项特性。
explicit Stonewt(int a);
仅仅关闭了隐式类型转换,但是仍然可以进行强制类型转换。
转换函数:
以上将数字转换为Stoewt对象。可以做相反的转换吗?
相关文章推荐
- C风格字符串 C++string对象 字符串常量 字符串直接量
- C++在VS2008的IDE环境中操作Excel2007(基础)
- c语言常见错误与注意点
- C语言中的单引号和双引号含义
- C++ Primer学习3:枚举类型
- log4Cpp学习(本文转载)
- c语言从文件中读入格式化数据并存入sqlite3
- C++常成员函数 - const 关键字
- C、C++一次将整个文件读入内存
- c++ 用类模版实现链表(c++语言程序设计第四版示例代码)
- dilworth解决的题目poj3636,poj1631
- 嵌入式C常见笔试题:字符串
- 再读effective c++
- C语言中动态的申请二(三)及多维数组的使用方法及释放方法
- C语言字符指针和字符数组的区别
- VC++动态链接库编程
- C++ 纯虚方法
- 转 值得推荐的C/C++框架和库
- 单链表的逆置-C++实现
- chapter12test4