[关闭]
@cxm-2016 2016-10-10T17:41:52.000000Z 字数 2940 阅读 1882

C++:类与对象

c++ 0

版本:2
作者:陈小默

开发环境:Visual Studio 2010

定义类

通常,C++程序将接口(类定义)放在头文件中,并将实现(类方法的代码放在源代码文件中),本文章以一个学生的例子来完成代码。

学生定义:记录三门课程(语文,英语,数学)的成绩,能够查看学生的平均成绩

创建头文件

现在创建名为student.h的头文件

  1. //student.h -- Student class interface
  2. //version 00
  3. #ifndef STUDENT_H_
  4. #define STUDENT_H_
  5. #include <string>
  6. class Student{ //class declaration
  7. private:
  8. std::string name;
  9. int ch;
  10. int en;
  11. int math;
  12. float average;
  13. void count(){
  14. average = (ch + en + math+0.0F)/3;
  15. }
  16. public:
  17. Student();//构造函数
  18. ~Student();//析构函数
  19. void setName(std::string name);
  20. void setChScore(int score);
  21. void setEnScore(int score);
  22. void setMathScore(int score);
  23. void show();
  24. };
  25. #endif

注意:类定义和结构体定义一样,要在最后加上(分号)

类和结构体

关键字class指明这些代码定义了一个类设计,在这里classtypename不是同义词,不能使用typename代替class

类描述看上去很像是包含成员函数以及public和private可见性标签的结构声明。实际上,C++对结构体进行了扩展,使之具有相同的特性。它们之间唯一的区别就是,结构体的默认访问类型是public,而类为private。C++程序猿通常使用类来实现类的描述,而把结构体作为纯粹的数据对象表示。

访问控制

在C++程序中通常使用访问控制关键字来保证自身属性的可见性。常见的三个关键字为privatepublicprotected

关键字 含义
private C++中的默认访问权限,也就是说上述student.h文件中的private关键字可以省略。其含义表示为只有该对象自身可以访问这些属性或者方法,被private修饰的属性和方法对于外部来说不可见。
public 公有权限,表示被public修饰的属性和方法可以被外部程序直接调用。
protected 受保护的权限,表示这些属性和方法仅仅能被该类和派生类的内部访问,也就是说,对于外部世界来说,保护成员的行为与private相同,对于派生类来说,保护成员的行为和public相同。

作用域解析运算符

在具体实现一个类之前,我们需要先了解一个运算符:作用域解析运算符(::)。该符号的作用是用来标识一个函数所属的类,例如当我们输入Student::average()时。表示我们访问的average()方法属于Student类而不是其他的类。
但是在一个Student类的内部我们并不需要使用使用作用域解析运算符就能访问average()方法,这是因为在类的内部自身所定义的所有方法对自身来说都是可见的。
对于一个方法名称来说,Student::average()是方法的函数限定名(全称),而average()方法属于非限定名(简称),当程序对于一个函数来源无异议时(没有重名方法),可以使用简称。

实现类成员

现在我们创建一个C++文件student.cpp

  1. //student.cpp -- implementing the Student class
  2. //version 00
  3. #include "stdafx.h"
  4. #include "student.h"
  5. Student::Student(){
  6. }
  7. Student::~Student(){
  8. }
  9. void Student::setChScore(int score){
  10. Student::ch = score;
  11. }
  12. void Student::setName(std::string n){
  13. Student::name = n;
  14. }
  15. void Student::setEnScore(int score){
  16. en = score;
  17. }
  18. void Student::setMathScore(int score){
  19. math = score;
  20. }
  21. //不需要知道这个方法的具体实现,后面会介绍,本节重点是类与对象
  22. void Student::show(){
  23. Student::count();
  24. ios_base::fmtflags orig = cout.setf(ios_base::fixed,ios_base::floatfield);
  25. std::streamsize prec = cout.precision(1);
  26. cout<<name<<" 同学的语文成绩为"<<ch<<"分,数学成绩为"<<math<<"分,英语成绩为"<<en<<"分,平均成绩"<<average<<"分"<<endl;
  27. cout.setf(orig,ios_base::floatfield);
  28. }

注意这个实现的Student::setChScore(int score)中我们在使用ch参数时使用了作用域解析运算符,其实在类的内部我们可以直接使用简称,所以在后续的方法中我们使用了非限定名。

默认的内联方法

我们在类的定义中声明并定义了一个count()方法,由于其位于声明中,编译器将其编译为内联方法。一般内容简单的方法都可以作为内联方法。如果我们并不想直接在类定义中定义一个内联方法,我们也可以在实现时给方法添加inline关键字。比如

  1. inline void count(){
  2. average = (ch + en + math+0.0F)/3;
  3. }

但是我们在声明外定义内联函数时必须注意C++中的一个规则:要求内联函数在每一个使用它的源文件中均有定义。也就是说我们需要在每一个使用该方法的文件中定义该方法,很明显我们并不想这样做,所以最好的实现就是在声明中实现定义方法。

创建对象

当我们在使用一个类的实例对象时需要用到一个关键字new,这个关键字和C语言中的malloc关键字类似,都是用来在堆内存中为数据分配一段空间。
我们在main方法中举个例子:

  1. //visual studio 2010 -- main program
  2. #include "stdafx.h"
  3. #include "student.h"
  4. int _tmain(int argc, _TCHAR* argv[]){
  5. Student *jack = new Student();
  6. jack->setName("jack");
  7. jack->setChScore(98);
  8. jack->setMathScore(100);
  9. jack->setEnScore(92);
  10. jack->show();
  11. delete jack;
  12. return 0;
  13. }

输出结果:

  1. jack 同学的语文成绩为98分,数学成绩为100分,英语成绩为92分,平均成绩96.7
  2. 请按任意键继续. . .
温馨提醒:记得养成良好习惯,在对象不用后要使用delete关键字销毁对象。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注