C++是一门博大精深的语言,本人对它的掌握仅限于会简单的应用、会看源代码即可,不敢求精通
一个类的例子
首先引用《c++ primer》 上的例子:
struct Sales_data{ //成员函数接口函数 string isbn()const{return bookNo;} //声明在类内,定义在类内 Sales_data& Combine(const Sales_data&); //声明在类内,定义在类外 double avg_price()const; //声明在类内,定义在类外 //类成员 string bookNo; unsigned units_sold; double revenue; }; //3个非成员接口函数 Sales_data add(const Sales_data&, const Sales_data&); ostream &print(ostream&, const Sales_data&); istream &read(istream&, Sales_data&); istream &read(istream &is, Sales_data &item){ double price = 0; is>>item.bookNo>>item.units_sold>>price; item.revenue=price*item.units_sold; return is; } ostream &print(ostream &os, const Sales_data &item){ os<<item.isbn()<<" "<<item.units_sold<<" " <<item.revenue<<" "<<item.avg_price(); return os; } double Sales_data::avg_price()const{ if(units_sold) { return revenue/units_sold; } else { return 0; } } Sales_data add(const Sales_data& a,const Sales_data &b){ Sales_data sum=a; sum.Combine(b); return sum; } Sales_data& Sales_data::Combine(const Sales_data &a){ units_sold+=a.units_sold; revenue+=a.revenue; return *this; }
成员函数的声明必须在类的内部,定义既可以内部也可以外部,作为接口的非成员函数只能在外部声明和定义
1、this指针
看看isbn函数:
string isbn()const{return bookNo;}
这个函数是如何获得bookNo成员的对象的呢?答案是类中的成员函数使用隐式参数this来访问调用它的那个对象,所以这里的代码还可以改为:
string isbn()const{return (*this).bookNo;}
或者
string isbn()const{return this->bookNo;}
可以把this理解为指向当前对象的一个常量指针,不允许修改this保存的地址值,这里的当前是相对于此成员函数而言的。
2、引入const成员函数
再看isbn函数的参数列表后紧跟关键字const,这里分析一下:
因为默认情况下this的类型是指向类类型非常量版本的常量指针,上面类中成员函数中,this的类型是Sales_data *const,虽然是隐式的,this依然需要初始化,所以不能把this绑定到常量对象,对于isbn函数而言,并不会改变当前对象,所以将this设置为指向常量的指针,但是this是隐式的,并不出现在参数列表,所以c++采用将函数参数列表后面加上const表示this是指向常量的指针,使用const的函数称为常量成员函数
构造函数
构造函数的作用是初始化类对象的成员,只有类的对象被创建,就会执行构造函数
构造函数没有返回值
构造函数不能被声明为const的,当创建一个const对象时,直到构造函数完成初始化过程,对象才能取得常量属性,故构造函数在const对象的构造过程中可以向其写值。
接下来在Sales_data类中定义3个构造函数,其中2个在类中定义,1个在外部定义:
struct Sales_data{ Sales_data(const string &s):bookNo(s){} Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){} Sales_data(istream &){} ...... };
构造函数初始值列表很简单,这里不详细介绍
访问控制与封装
接下来使用访问修饰符来重新定义Sales_data类
class Sales_data{ public: Sales_data(const string &s):bookNo(s){} Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){} Sales_data(istream &){} string isbn()const{return bookNo;} Sales_data& Combine(const Sales_data&); private: double avg_price()const {return units_sold?revenue/units_sold:0;} string bookNo; unsigned units_sold; double revenue; };
总结:当希望定义的类的所有成员是public时,使用struct,反之希望成员是private的,使用class
总结就到这里,如果你还有补充,请留言告诉我,enjoy it 🙂
Comments