随笔-145  评论-173  文章-70  trackbacks-0

以下是几点学习C++后续内容的体会和注意之处,更新ing…………

对于类的几点认识:
---------《以下的几条规范是便于多文件管理,分别编译的》---------
1.将类的声明放在h文件中,注意是声明,而不是定义,命名之,最好用类

名来给这个h文件命名。
2.将类的定义放在cpp文件中,单独一个cpp文件中,以类名命名之。
3.将主函数放在单独一个文件cpp中,文件名无所谓,不过取main的话便于

找到主体程序在哪里。

 

下面要说的是虚函数:virtual
1.在类中要声明virtual,但是放在对应的定义cpp文件中的时候,要注意去

掉virtual,否则会报错。
2.注意声明和定义的原型都必须完全一样,比如声明中有一个const,那么

在定义中必须也要有,否则的话就会报错,说不认识这个函数。
3.在类外定义的话一定要加上类型限定符,作用域限定符。

 下面写点代码:

student.h头文件 
1
#ifndef STUDENT_H
 2#define STUDENT_H
 3
 4#include <iostream>
 5using std::string;
 6
 7
 8class Student
 9{
10public:
11    Student(const string& a="",double b=0.0,int c=0):score(b),name(a),number(c)
12    {}
13    ~Student(){}
14    //void show_score();
15    //void modify(Student& a);
16    friend Student operator+(Student& a,Student& b);
17    friend Student operator-(Student& a,Student& b);
18    friend std::ostream& operator<<(std::ostream &a,Student& b);  //改变状态的一般都要定义为类成员,++,--及*
19    friend std::istream& operator>>(std::istream &a,Student& b);//进行算术运算和输入输出的就定义为友元
20    //Student& operator=(Student& a);
21private:
22    double score;
23    string name;
24    int number;
25}
;
26
27#endif

 

 1student.cpp文件,实现类函数
 2#include <iostream>
 3#include <string>
 4#include "Student.h"
 5using std::cout;
 6using std::cin;
 7using std::endl;
 8
 9Student operator+(Student& a,Student& b) //这里面又用到了<<这个运算符的。而这个你已经自定义了啊!
10{
11    cout << a.name << "" << b.name << "分数之和为:" << a.score+ b.score;
12    cout << endl;
13    return a;
14}

15Student operator-(Student& a,Student& b)
16{
17    cout << a.name << " 比 " << b.name << "" << 
18        (a.score > b.score)?(a.score-b.score):(b.score - a.score);
19    cout << endl;
20    return a;
21}

22std::ostream& operator<<(std::ostream &a,Student& b)
23{
24    a << b.name<<"的分数:" << b.score << "\t 学号:" << b.number << endl;
25    return a;
26}

27std::istream& operator>>(std::istream &a,Student& b)
28{
29    a >> b.name >>b.number >> b.score  ; 
30    return a;
31}

32/*
33问题1,修改定义函数的时候没有修改声明,为什么这么粗心呢?
342.返回值,特别是对于有输入输出流的,要有返回值啊!
353.流的返回值和调用。
364.返回值怎么能为void呢?因为要输出a+b,所以要返回一个值啊,相当于opreator+(a,b)
37*/

 

主函数:main.cpp 
1
#include <iostream>
 2#include "Student.h"
 3
 4using namespace std;
 5
 6int main()
 7{
 8    Student a,b;
 9    cout << "依次输入姓名,学号,成绩" << endl;
10    cin >> a >> b;
11    cout << a << b;
12    cout << endl;
13    return 0;
14}

15

 我想说的是自己遇到的几个问题:
1.重载<< 和>>操作符:这两个操作符只能作为友元而不是成员函数。作为重载运算符,有两种定义形式,即:成员函数形式和非成员函数形式,对于成员函数的形式,它的声明方式是形参数要比操作数少一个,为什么呢,因为省略了默认的形参this指针,而这个省略的形参正式左操作数,即定义这样的运算符的时候,this指针指向的是左操作数。其次,就是非成员函数,即友元声明方式。友元声明方式较简单合理,形参数和操作数相同,显示的是合理的调用函数的方式。
2.什么时候用成员函数的声明方式,什么时候用友元函数的声明方式?此部分需注意的是:1,对于=,(),【】,->这四个操作符只能作为成员函数来声明,想想这个是为什么呢?
  (1)只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。
  (2)单目运算符最好重载为成员函数。
  (3) 对于复合的赋值运算符如+=、-=、*=、/=、&=、!=、~=、%=、>>=、<<=建议重载为成员函数。
  (4) 对于其它运算符,建议重载为友元函数。
关于此问题的详细讨论,见:http://www.rupeng.com/forum/thread-4468-1-1-uid3573.html
在C++编程思想中有述,据网友而言,大意是:如果可以定义为全局变量的话,那么就可以定义为int operator =(int,mytype),而这种方式的话就不对了,因为赋值=是和左边的类紧密相连的,所以会定义为成员函数的……

 此部分详细关注中………………

3.关于重载运算符的返回值的问题:
我们是不是已经习惯于重载运算符有一个返回值类型呢?对,是的,我们经常这么干,现在的问题是,如果我定义为void的话,会出错吗?
不会的,将上面的换成void的返回值照样不会出错!
为什么呢?因为定义有返回值只是我们的一个习惯,为何有返回值,因为我们要返回值,很白痴吧?可是事实就是这样,想想这个:
cout << a + b;  这个代码很简单是吧,a+b 实际上就是operator+(a,b)的一个等价形式,我要能够cout ,那么必然有一个返回值,否则的话调用这个函数没有返回值的话我怎么cout它呢?于是乎我们在定义加法的重载的时候就只能在前面加上a和b的类型了。
好,现在我没有类型了,void,怎么办?很简单,直接用 a + b;  因为它相当于:operator+(a,b);也就是调用一个函数,直接调用,没有返回值。
当然,结果也还是对的,各位可以看看…………

注意我想说的,学习计算机主要的是学习那个思想,而不是片面的记住语法或者其他,要想想为什么需要这样,这样我们的思维才会和计算机接近,才能更好的理解计算机,上面的这个例子就是很好的说明,这个函数很另类了吧,可是它完全符合各种语法,能够顺利运行。。
可是要记住的是,重载运算符为什么要重载,就是为了使用和内置类型一样的自然,如果像上面我定义的void那样,那么恐怕就很难懂了,如果将减号定义为加法的话,那么就更加的匪夷所思。也很难读了,违背了初衷,也就是一种错误的做法了,虽然理论上是可行的。。

计算机是一个很奇妙的东西,需要我们用心去体会……
                                                                                                                  ------------------------------<本章完>

 

 

 

 

 

 

 

 

 

 

posted on 2009-09-28 21:36 deercoder 阅读(585) 评论(0)  编辑 收藏 引用 所属分类: C/C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理