C++使用类和对象
1、 内置函数
程序调用函数时需要一定的时间和空间开销,其执行过程一般如下:
而C++提供了一种高效率的方法,即在编译的时候将所调用函数的代码直接嵌入到主函数中,而不是将流程转出去,这样可以避免函数调用时频繁的转入与转出操作,从而节省过程中“保存现场”和“恢复现场”所需的时间。如下代码:
#include<iostream> using namespace std; inline int max(int,int,int); int main() { int i=1,j=2,k=3; int m=max(i,j,k); cout<<"max="<<m<<endl; return 0; } inline int max(int a,int b,int c){ if(b>a) a=b; if(c>a) a=c; return a; }
内置函数虽然节省了程序的运行时间,但会增加目表函数的长度,这也是不利的,需要综合分析后使用。
2、 成员函数
如下简单案例
#include<iostream> #include<string> using namespace std; class Student{ public: void display(); void set(); private: int num; char sex; string name; }; void Student::display() { cout<<"num:"<<num<<endl; cout<<"sex:"<<sex<<endl; cout<<"name:"<<name<<endl; } void Student::set() { cin>>num; cin>>sex; cin>>name; } int main(){ Student stu; stu.set(); stu.display(); return 0; }
成员函数在类外定义的时候,必须在函数名前加上类名,予以限定,“::”表示作用域限定符,用它声明函数属于哪个类。
注意:如果函数在类外定义时,系统不会将其认为是加了inline的内置函数,这些成员函数的调用和普通的函数调用相同,这样有利于类的接口和类的实现相分离,利于信息的隐藏。
3、 带参数的构造方法
以一个简单的案例说明:
#include<iostream> #include<string> using namespace std; class Box { private: int height; int width; int length; public: Box(int,int,int); int volume(); }; Box::Box(int h,int w,int l){ height=h; width=w; length=l; } int Box::volume() { return height*length*width; } int main(){ Box box1(12,25,10); cout<<"the volume of box1 is "<<box1.volume()<<endl; return 0; }
也可以通过参数初始化表对数据成员初始化,将类中的构造方法进行改写,如下:
class Box { private: int height; int width; int length; public: Box(int h,int w,int l):height(h),width(w),length(l){}; int volume(); };
注意如果类中的数据成员是数组,则应在构造函数体中用语句对其赋值,而不能在参数初始化表中对其初始化。如下案例:
class Student {private: int no; char name[20]; public: Student(int n,char nam[]):no(n){ strcpy(name,nam);}; void display(); }; void Student::display(){ cout<<no<<" "<<name<<endl; } int main() { Student stu(1,"郭庆兴"); stu.display(); return 0; }
或者这样
class Student {private: int no; string name; public: Student(int n,string nam):no(n),name(nam){}; void display(); };
4、 构造函数的重载
如下面一个简单的代码案例:
#include<iostream> #include<string> using namespace std; class Box { private: int height; int width; int length; public: Box(); Box(int h,int w,int l):height(h),width(w),length(l){}; int volume(); }; Box::Box(){ height=10; width=10; length=10; } int Box::volume() { return height*length*width; } int main(){ Box box1; cout<<"the volume of box1 is "<<box1.volume()<<endl; Box box2(12,25,10); cout<<"the volume of box1 is "<<box2.volume()<<endl; return 0; }
注意:当建立对象使用无参构造函数函数时,要注意语句的书写:
Box box1;
而不能写成:
Box box1(); //错误
以上错误的语句并不是定义Box对象,而是定义一个返回为Box的普通函数。
5、 使用默认参数构造函数
如下案例:
#include<iostream> #include<string> using namespace std; class Box { private: int height; int width; int length; public: Box(int h=10,int w=10,int len=10):height(h),width(w),length(len){}; int volume(); void display(); }; int Box::volume() { return height*length*width; } int main(){ Box box1; cout<<"the volume of box1 is "<<box1.volume()<<endl; Box box2(12,25); cout<<"the volume of box2 is "<<box2.volume()<<endl; Box box3(12,25,30); cout<<"the volume of box3 is "<<box3.volume()<<endl; return 0; }
因此在编写设有默认参数的构造方法的时候,不可以有两个构造方法,如下:
Box(int h=10,int w=10,int len=10);
Box();
这样如果一旦执行“Box box;”,系统就不能分别是以哪个构造方法为基准建立构造函数。
6、 析构函数
析构函数是一个特殊的成员函数,它的名字是类名前面加上“~”符号。在C++中“~”是取反运算符。可以联想到它是与构造函数起相反的作用。析构函数的作用是在撤销对象占用的内存之前,完成一些清理工作。
析构函数不返回任何值,没有函数类型,也没有函数参数。由于没有函数参数,因此它并不能重载,即一个类只能有一个析构函数。
如下案例:
#include<iostream> #include<string> using namespace std; class Student {private: int no; string name; char sex; public: Student(int n,string nam,char s){ no=n; name=nam; sex=s; cout<<"Constructor"<<no<<" called!"<<endl; } ~Student(){ cout<<"Destructor"<<no<<" called!"<<endl; } void display(){ cout<<"no : "<<no<<endl; cout<<"name : "<<name<<endl; cout<<"sex : "<<sex<<endl; } }; int main() { Student stu1(1,"郭庆兴",'m'); stu1.display(); Student stu2(2,"test",'f'); stu2.display(); return 0; }
结果如图所示:
可知,对于构造函数,程序先执行stu1的构造函数,再去执行stu2的构造函数;而对于析构函数来说,程序先执行stu2的析构函数,再去执行stu1的析构函数,这就十分类似于栈的特性了。对于“同一级别”的构造函数个析构函数是这样的,那么不同“级别”,则不是这样的,这里以局部变量和全局变量来举例。如下代码:
int main() { Student stu1(1,"郭庆兴",'m'); stu1.display(); static Student stu2(2,"test",'f'); stu2.display(); return 0; }
在stu2对象前面加上一个static即可,此时stu2是静态变量,它一直到程序全部运行结束后才会释放。结果如下图:
7、 对象数组
数组不仅可以存放简单变量,还可以存放由类组成的对象。如下案例:
#include<iostream> #include<string> using namespace std; class Box { private: int height; int width; int length; public: Box(int h=10,int w=10,int len=10):height(h),width(w),length(len){}; int volume(); void display(); }; int Box::volume() { return height*length*width; } int main(){ Box a[4]={ Box(), Box(20), Box(10,30), Box(10,10,40) }; cout<<"the volume of box1 is "<<a[0].volume()<<endl; cout<<"the volume of box2 is "<<a[1].volume()<<endl; cout<<"the volume of box3 is "<<a[2].volume()<<endl; cout<<"the volume of box4 is "<<a[3].volume()<<endl; return 0; }
结果如图所示: