C++学习随笔8 面向对象编程(1)- 类

  • 类定义
 1 #include <iostream>
 2 #include <iomanip>
 3 using namespace std;
 4 
 5 class Date{
 6     int year, month, day;
 7 public:
 8     //成员函数定义(在类的内部)
 9     bool isLeapYear(){
10         return (year%4==0 && year%100 != 0) || (year%400==0);
11     }
12     void set(int y, int m, int d) {year = y; month = m; day = d;}
13    //成员函数声明,定义在类的外部
14     void print();           
15 };     //定义类,必须加分号
16 
17 //成员函数定义,必须加类型名和命名空间引导符::
18 void Date::print(){
19     cout<<setfill('0');
20     cout<<setw(4)<<year<<'-'<<setw(2)<<month<<'-'<<setw(2)<<day<<'\n';
21     cout<<setfill(' ');
22 }
23 
24 int main(){
25     Date d;           //创建对象
26     d.set(2000, 12, 6);
27     if(d.isLeapYear())
28          d.print();
29 }

注意:只要是在类定义中包含的函数,就有默认声明内敛的性质,也就说该函数处于被编译自动安排到最佳运行性能的状态。因此,为了获取最佳性能,就应该在类编程时尽量把函数写入类定义中,使之称为成员函数。但编译是否真的将成员函数安排为内敛,还要看函数是否足够简单,是否包含不适于内敛运行的循环结构。所以,应尽量将成员函数的定义写到类定义的外部

常成员函数:该成员函数不会改变对象值,在常成员函数中,任何改变对象值的操作,都将被编译器毫不留情地认定为错误。

                 常成员函数的声明和定义在形式上必须一致,即在函数形参列表的右括号后面加上const

 1 class Date{
 2       int year, month, day;
 3 public:
 4      void set(int y, int m, int d);
 5      bool isLeapYear()const;
 6      void print()const;           
 7 };
 8 
 9 //显示内敛
10 inline void Date::set(int y, int m, int d) {year = y; month = m; day = d;}   //会改变对象至所以无法声明和定义成常成员函数
11 inline bool Date::isLeapYear() const{
12      return (year%4==0 && year%100 != 0) || (year%400==0);
13 }
14 inline void Date::print() const{
15      cout<<setfill('0');
16      cout<<setw(4)<<year<<'-'<<setw(2)<<month<<'-'<<setw(2)<<day<<'\n';
17      cout<<setfill(' ');
18 }

重载成员函数:成员函数与普通函数一样,可以重载。

  • 操作符

操作符重载:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Point{
 5  int x, y;
 6 public:
 7  void set(int a, int b){x=a; y=b;}
 8  void print()const{cout<<"("<<x<<", "<<y<<")\n";}
 9  friend Point operator+(const Point &a, const Point &b);//作为外部函数要访问类的私有数据,必须加friend;若变为成员操作符即Point operator+(const Point &b);
10 };
11 
12 Point operator+(const Point &a, const Point &b)
13 {
14   Point s;
15   s.set(a.x + b.x, a.y + b.y);
16   return s;
17 }
18 
19 int main(){
20   Point a, b;
21   a.set(3, 2);
22   b.set(1, 5);
23   (a+b).print();
24   operator+(a, b).print();                             //a+b会被C++转译为operator+(a, b)
25 }

性质:

1.不能创建新的操作符

2.个别操作符不能重载("::"、"."、"? :"、sizeof、typeof)

3.优先级和结合性不变,重载操作符后,其优先级和结合性不变。

4.操作数个数不变,原先的操作符是单目的,重载也是单目形式的。

5.专门处理对象,即至少有一个参数是自定义类型。

6.忌意义相左,操作符重载后的新意义应该反应操作的本质。

增量操作符重载:

X& operator++(X &a);                    //前增量操作符,返回对象的引用

++a;                                            //等价于operator++(a);

X   operator++(X &a, int n);           //后增量操作符,返回对象

a++;                                           //等价于operator++(a, 1);

成员操作符:

成员操作符声明和定义中省略了第一个参数,因为成员函数总是与对象捆绑使用的,被捆绑的对象就是被操作的第一个参数。因此,单目成员操作符没有参数,双目成员操作符只有一个参数。

s+t   ==  s.operator+(t)

类的程序架构:

类的定义放在头文件中;类的实现放在一个单独的.cpp文件中;类的应用放在别的.cpp文件中。

  • 静态数据成员

 静态数据成员在类外分配空间和初始化,应省略static

class Student{                                 class Student{
   static int number = 0;      ==              static int number;
   ...                                         ...
};                                             };
                                               int Student::number = 0;

//静态数据成员在类内初始化不能放在头文件中,通常应将其放在类的实现代码中。
  • 静态成员函数

通常应该将静态数据成员设为私有的,用静态成员函数去访问静态数据成员。

静态成员函数如果不在类中实现,而在类的外部实现时,类名前应该免去static关键字。成员函数的静态性只在类中声明的时候才是必要的。

注意:

因为静态成员函数可以不捆绑对象的形式调用,静态成员函数被调用时,没有当前对象的信息,所以静态成员函数不能访问非静态数据成员

  • 友元(friend) 

private成员只能被本类成员函数、友元函数或友元类的成员函数访问,不能被派生类访问,该类对象也不能访问;

protected成员可以被该类中函数,子类中的函数,其友元函数访问,但不能被该类对象访问;

public成员可以被任意访问,该类对象也可以访问;

1.普通函数声明为类的友元,就可以直接访问类的私有数据;

2.友元还经常用在操作符重载中,例如:friend ostream& operator<<(ostream& o, const Point& d);   cout<<d;

3.成员函数可以是另一个类的友元:例如,教师应该可以修改学生的成绩,可以访问学生类的私有数据,故将教师类中的assignGrade成员函数声明为学生类的友元;

 1 class Student;//因为Teacher类中有Student的声明,Student中有Teacher类的声明,而类型名使用之前必须声明,所以这里在Teacher类定义之前,先声明Student类,称为前向声明
 2 class Teacher{
 3      Student * pList;
 4 public:
 5      //...
 6 //注意,首先我们声明Student,是为了在Teacher类中assignGrade方法可以使用其引用类型的形参,而该方法的定义需要放到Student类定义之后,因为此时才知道Student类型有哪些成员。
 7      void assignGrade(Student &s);  
 8 };
 9  
10 class Student{
11      Teacher* pT;
12      int semesterHours;
13      double grade;
14 public:
15      //...
16      friend void Teacher::assignGrade(Student &s);
17 };
18 
19 void Teacher::assignGrade(Student &s)
20 {
21      s.grade = 100;
22 }

 

4.整个类也可以是友元,此时称该类友元为友类。友类的每个成员函数都可以访问另一个类中的私有成员。例如,将整个教师类看作是学生类的友类,教师既可以修改成绩,又可以调整学时数:

 1 class Student;
 2 class Teacher{
 3    Student* pList;
 4 public:
 5     void assignGrade(Student &s);
 6     void adjustHours(Student &s); 
 7 };
 8 
 9 class Student{
10    Teacher* pT;
11    int semesterHours;
12    double grade;
13 public:
14    //...
15    friend class Teacher;
16 };

 

posted @ 2016-11-28 15:12  etcjd  阅读(334)  评论(0)    收藏  举报