注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

(转载)C++小知识32——一段代码引起的思考(运算符的重载)  

2012-01-05 10:19:35|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

今天在网上又看到运算符重载的一些需要注意的地方,转过来。非常感谢这位同学。

一段代码引起的思考-----编译器
http://blog.csdn.net/maochencw/article/details/7103411

分类: c++ 编译器 2011-12-27 13:20 90人阅读 评论(0) 收藏 举报
今天碰到一个问题,同学写了一段操作符重载的代码,但是总是编译不过,总是提醒'operator <<' is ambiguous,这是指'<<'被多次定义了,他用的是vc++ 6.0,代码如下:
view plain
#include <iostream> 
 
using namespace std; 
 
 
 
class Point 
 

 
public: 
 
    Point(float x=0,float y=0); 
 
    void setPoint(float,float); 
 
    float getXpoint() const {return x;} 
 
    float getypoint() const {return y;} 
 
    friend ostream & operator<< (ostream & os,Point & p); 
 
private: 
 
    float x; 
 
    float y; 
 
}; 
 
 
 
Point::Point(float a,float b) 
 

 
    x=a; 
 
    y=b; 
 

 
 
 
void Point::setPoint(float a,float b) 
 

 
    x=a; 
 
    y=b; 
 
 
 

 
 
 
ostream & operator<< (ostream & output,Point & p) 
 

 
   output << "[" <<p.getXpoint()<<","<<p.getypoint() << "]" << endl; 
 
   return output; 
 

 
 
 
int main() 
 

 
    Point p(4.5,5.5); 
 
 
 
    cout << "x=" << p.getXpoint() << ",y=" << p.getypoint() << endl; 
 
    p.setPoint(8.5,9.5); 
 
    cout << p; 
 
 
 
    return 0; 
 

这是比较平常的重载‘<<’的例子,我猜想是全局命名空间造成编译不过的,于是我们把最开始的using namespace std这句话去掉,以std::cout和std::endl代替之,再次编译,通过。
我把未修改过的代码用gcc 4.4.3编译一下,也通过了,相同的代码在不同的编译器上也可能会有不同的结果。
在这里我想到了程序的可控性问题,怎样让变量和数据的传递在控制之中,让程序的通用性比较好,避免出现在这个编译器上编译通过,而在另外一个编译器上编译错误,通过这个列子,尽量不要使用全局的命名空间,而使用std::cout和std:endl等代替。

一段代码引发的思考-----(类及操作符重载,数组相加)
分类: c++ 操作符重载 数组 class 2011-12-26 16:28 124人阅读 评论(0) 收藏 举报
平时照着书上敲代码,没有发现什么错误,最多是自己失误把字母敲错了,可是轮到自己写代码时,出现了一大堆错误,错误五花八门,但是主要还是对知识概念不熟造成的,学习编程语言的时候还是要多做练习,光敲书上的例子是得不到多大进步的。

这个代码是定义一个重载函数,重载‘+’,使其完成数组相加的功能,最后返回结果。
view plain
#include <iostream> 
 
class test  //类名 

private: 
    int m[2]; 
public: 
    test();   //构造函数 
    test(int c[]); 
    test operator+(const test & t)const; //重载操作符‘+’ 
    void Show1() const;    //显示结果 
}; 
 
test::test() 

    m[0] = 0; 
    m[1] = 0; 

 
test::test(int c[]) 

    int i; 
    for(i = 0; i < 2; i++) 
    { 
        m[i] = c[i]; 
    } 
 

 
test test::operator +(const test & t)const  //重载操作符'+' 

    test sum; 
    sum.m[0] = m[0] + t.m[0]; 
    sum.m[1] = m[1] + t.m[1]; 
 
    return sum; 

 
void test::Show1()const 

    std::cout << "array = " << m[0] + m[1] <<std::endl; 

 
int main() 

 
    int ar0[2] = {1, 2}; 
    int ar1[2] = {3, 4}; 
 
    test array0(ar0); 
    test array1(ar1); 
 
    array0.Show1(); 
    array1.Show1(); 
    test to; 
 
    to = array1 + array0; 
    to.Show1(); 
 
    return 0; 

源代码如上,首先定义了一个test类,私有成员是一个长度为2的int数组,公有成员四个,一个是构造函数test(),在这里要注意,构造函数的名称要与类名相同(析构函数是在类名前加一个‘~’符号),它的主要作用是初始化数组,这个从后面的函数定义就可以看出来,将数组初始化成零,test(int c[ ]),构造函数的参数名称不能和类成员名称相同,所以不能使用int m[ ]作为构造函数的形参。
test operator+(const test & t)const为操作符重载函数,其中operator+为函数名,表明重载操作符‘+’,最前面一个test表明函数的返回值为test类,最后面的一个const可以保证重载函数不修改调用它的类,在本例中,可以保证重载函数不修改array1,括号里的const表示test & t在其寿命周期内不能被改变,&t是一个引用,是作为调用函数实参的引用,它的类型是test类。(小提一下const和define的区别,两者都可以定义常量,define只是相当于文本替代,而const定义了常量的类型).
void Show1()const,后面的const同样是为了防止Show1()改变调用对象而设置的。
下面来看一下函数的定义,前面已经说了,第一个构造函数主要是将数组初始化为零;在C++中,有私有成员和公有成员,使用类对象的程序都可以直接访问公有部分,但是只能通过公有成员函数访问私有成员,所以第二个构造函数的作用是将非类成员数据赋给类的私有成员数据。在看重载函数之前,我们看一看主函数中这一段代码:to = array1 + array0;这句话实际上实在调用重载函数,其中array1为调用函数的对象,array0为调用函数的实参,这段代码等价与array1.operator+(array0),函数定义中的sum.m[0] = m[0] + t.m[0]等价于sum.m[0] = this->m[0] + t.m[0],这句代码的意思是将array1和array0数组的第一个元素相加,然后存于test对象sum的数组m[ ] 的第一个元素中,函数定义的最后返回sum。
函数还可以进行进一步扩展,用const int LEN = 2代替直接写出数组长度,数组内容由用户从键盘输入,而不是在程序里预先赋值。

现在发现自己还有很长一条路要走,在这条路上,当你能够用程序将你心中所想轻而易举的表达出来时,你离成功就很近了。

  评论这张
 
阅读(634)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017