c++使用类

来源:互联网 发布:朋友圈文章制作软件 编辑:程序博客网 时间:2024/04/29 16:14

运算符重载

声明和定义定义

operatorop(argument-list)
void operator+();void operator[]();
重载的运算符必须是已有的运算符不能重载operator@();因为@不是c++的运算符

使用重载的运算符

//头文件...class A{private:...public :...A& operator+(const A&);}

//源文件....A& A::operator_(const A & a){return a;}
如果想上面那样定义,我们就有两种使用方法
1使用定义时的函数
A a;A b;a.operator+(b);
2使用运算符
A c=a+b;
上面的两种方法是等价的,不过你请注意前面a相当于函数的调用者,酣眠的b相当于函数的参数,所以反过来是不可以得,但是友元的非成员函数可以解决(稍后讲).
注意
1重载运算符之后最少有一个操作数是用户定义的,这将防止用户为标准类型重载运算符,比如不能减号重载为两个double的和
2运算符重载不能违反原来运算符的句法规则,比如不能将%重载成使用一个操作数,因为原来%是两个操作数的
3不能改变运算符的优先级。
4不能穿件新的运算符
5不能创建下面的运算符
sizeof
.
.*(成员指针)
::
?:(运算符)
typeid(一个RTTL运算符)
const_cast
dynamic_cast
reinterpret_cast
static_cast
上面都是不可以的 ,但是有些运算符必须为成员函数重载
=
()
[]
->
6除了正式的限制 重载运算符最好表示出意义,比如*最好不要重载成交换

友元

1友元函数
2友元类
3友元成员函数
通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的权限,为什么需要友元呢?
A=B*0.25;
将转换为下面的成员函数的调用
A=B.operater(0.25);
但是反过来呢?
A=0.25*B;
这样就不行了 ,这时候友元就可以帮助我们;
第一步我们要在类中声明 如下
friend A operater*(double m,const A& b);
1 虽然operator*()函数是在类声明中声明的,但它不是成员函数,因为不能使用成员函数运算符调用
2虽然operator*()不是成员函数,但是它与成员函数的访问权限相同
第二步因为不是类的所以不需要作用域限定股,也不需要使用关键字friend

类的自动转换和强制转换

自动转换

在c++中接受一个参数的构造函数为 将类型与该参数形同的值转换为类提供了蓝图
比如类中定义了
A(double );A a;a=11.1;

上面用A(double)创建了临时时A的变量 并且用11.1初始化,随后采用逐成员赋值的方式将该临时变量复制到a中,这一过程为隐式转换,还有一点就是如果构造函数中有默认参数也可以完成这样的隐式转换,但是注意不能同时出现这样会出项二义性
注意:
c++11关键字explcit用于关闭这种自动变量

接下来我们总结什么时候编译器会进行这种隐式转换
1将类A初始化为double
2将double 赋值给A
3将double赋值给接受A类参数的函数时
4返回声明为A时,用double
5在上任意述情况下,使用可转换为double类型的内置类型
当然对于最后一点 如果在函数中有很多类型的构造函数例如 A(long)你传进去一个int的参数 将会出现二义性 ,int可以转为long也可以转换为double

转换函数

上面是把对象转换为数字,那么反过来可以吗,答案是可以。转换函数是用户定义强制类型转换,如下定义
operater typeName();
1转换函数必须为类的方法
2转换函数不能指定返回值
3转换函数不能有参数
当我们定义玩转换函数之后我们就可以用了比如我们定义一个
operater double();
1强制转换
A a;double d1=double(a);//显示转换double d2=(double)a;double d3=a; //隐式转换
对于隐式的转换 一定要注意二义性,例如有一个类的对象a中有两个类型转换函数
operater int();
operater double();
在下面这种情况下
cout<<a<<endl;
会怎么样呢?答案是编译器会报错二义性,因为编译器不知道是转换为int还是double 来输出,对于int和double转换long也会出现二义性
注意 explicit也可以用在转换函数上面。




0 0