c++关于类的基础学习

c++类 :在c++中大体分为两种,一 内置类型,如int double用户等  二 用户自定义类UDT

       问:为什么要使用用户自定义类?

       答:编译器不可能知道我们想使用的全部类型。但是标准库类型已经给我们提供了一些非常有用的类,比如vector,string,ostream等等,但是远不能满足需求。尤其是在面向对象的程序设计中,我们需要用自定义的一个类型独立的去表示这个对象的一些特性,所以在面向对象的程序中我们看到更多的是一个一个的对象,而在c程序中我们看到更多的是函数和表达式。类又是描述一个对象的关键和基础。

  1.      类的表达形式:

       class X{

   public:

      int m;

      int mf(int v){int odd = m;m = v;return odd}

};

用来定义类的组成部分,它们叫成员。读取成员规则如下:

X var;

var.m = 7;

var.mf(9);

 

2.接口和实现

class X{

public:

       //这个是接口的标识,它是公共的

private:

      //这个是实现标识,它是私有的

}

成员默认是私有的,即如果不加标识,就等同于私有

http://soft.chinabyte.com/database/340/12457340.shtml   经典 什么是不变式

c++提供了一种可用来描述没有私有实现的细节的类,就是 结构体

struct X{

int m;

} ; 等价于

class X{

  public:

           int m;

};

2.成员函数和构造函数

struct Date{                              struct Date{

            int y;                                                                                       int y,m,d;

     int m;                                                                                       Date(int y,int m,int d);//与类同名的成员是特殊成员,叫构造函数,

                                            专门用于初始化。类型本身具有一个需要参数的构造函数,如果程序员忘了利用,系                                                                                                                统会报错!!!

         int d;                                                                                        void add_day(int n);

} ;                                                                                                             };

                                      例如:

                                      Date mybirthday;//error:mybirthday not initial

Date today;                                                                                                Date today(12,24,2007);//error 日期不合法

today.y = 2005;                                                                                         Date last(2000,12,31);//right

today.m = 24;//error 非法月份                                                                   Date christams = Date(1976,12,24);//ok 麻烦

today.d = -3;//非法日期  我们需要辅助函数来进行初始化检查,数据合法性检查

2.保持细节私有性

上述结构体方式,用户可以任意修改结构体中的数据,比如 Date last(2000,12,31); 

                           last.m = 14;//非法,不合理的月份

为了避免这种大的错误,我们让数据私有,不能让用户随意修改,但是会提供一个公有函数仅供用户访问。

class Date{

         private:

         int y,m,d;

         public:

         Date(int y,int m, int d);

         void add_day(int n);

         int year(){return y};

         int month(){return m};

         int day(){return d};

};

Date last(2000,12,31); 

 

count<< last.month();<<endl;//ok

判定有效值得规则称为不变式

如果我们不需要对处理的数据,规定不变式,那我们处理的就是普通数据,那就用struct,不用使用类了

struct不能对自身结构中的数据进行保护,所有的数据都是public的,可以随意修改

3.定义成员函数

在类外定义成员函数的语法规则:

Date::Date(int yy, int mm,int dd)

    :y(yy),m(mm),d(dd)

{

}类成员初始化的语法

void Date::add_day(int n)

{

}

... ...

我们也可以在类中定义成员函数,但是不建议这么做,过大的成员函数,会影响接口的展现。

如果像 int month(){return m};这样内容比较少的成员函数,放在内部看起来更为直接,我们也可以考虑放在类中

成员函数定义在类的内部两个作用:

1.函数将成为内联的,即内联函数,编译器为此函数调用生成代码时,不会真正的生成函数调用,而是将代码嵌入到调用者代码中。对于month()这种函数,代码少,频繁调用,这种方式会带来性能的提升

2.每当我们对内联函数体做出修改时,所有使用这个类的函数不得不重新编译。如果函数体位于声明之外的话,就不必这样,只在类改变接口的时候才需要重新编译程序。对于大程序老说,函数体改变时无需重新编译程序会是一个极大的优势

总结:除非你明确需要从小函数中获得性能提升,否则不要将成员函数放在类声明中。对于五行以上的函数,不会从内联中获益。对于超过一两个表达式的函数,不建议采用内联函数。

4.引用当前对象

void f(Date d1,Date d2)

{

  count<<d1.month<<d2.month<<endl;

}

每个成员函数都有一个隐式参数,用来识别调用它的对象

5.报告错误

发现无效日期我们需要抛出一个异常

class Date{

pubilic:

class Invalid{};

Date(int y,int m,int d);

private:

int y,m,d;

bool check();//哪些函数放在私有实现,哪些放在公共接口,怎么划分

};

Date::Date(int yy,int mm,int dd){

if(!check())throw Invaild();//check返回值是false,这么表示有问题啊

}

bool Date::check()

{  if(m<1||m>12) return false;

};

void f(int x,int y)

try{

     Date dxy(2004,x,y);

     count<<dxy<<endl;

     dxy.add_day(2);

}

catch(Date::Invaild){

error("Invaild date");

}

 

 

posted @ 2016-01-12 11:48  耀匀  阅读(205)  评论(0编辑  收藏  举报