1.c++类的声明和定义。
class student{
public:
char *name;
int age;
float score;
void say();
};
void student :: say()
{
cout<<name<<", age:"<<age<<", score"<<score<<endl;
}
这里的函数可以先在类中声明,然后把定义放在外面。这样做完全合法,同时也便于阅读。
C++中类定义类的声明部分一般分为类声明部分和类的实现部分。类的声明部分用来说明类中的成员(数据成员,数据函数),告诉使用者干什么。
类实现部分用来定义成员函数,该函数用来对数据成员进行操作,告诉使用者怎么干。
类的定义的一般形式 :
class <类名 >
{
public:
<成员函数或变量 >;
protected:
<成员函数或变量 >;
privated:
<成员函数或变量 >;
};
#include <iostream>using namespace std;class data //类的声明部分{public:void setdata(int y, int m, int d);int isleapyear();void print();private:int year;int month;int day;}; //到此为止void data :: setdata(int y, int m, int d) //类的实现部分{year = y;month = m;day = d;}int data :: isleapyear(){if (((year %4 == 0) && (year %100 != 0)) || (year %400 == 0)){return 1;}else{return 0;}}void data :: print(){cout<<year<<"."<<month<<"."<<day;} //到此为止int main(){int flag;data dat1;dat1.setdata(1995,2,20);flag = dat1.isleapyear();if (1 == flag){dat1.print();cout<<" is leapyear"<<endl;}else{dat1.print();cout<<" is not leapyear"<<endl;}return 0;}
类体定义类的成员:
1)数据成员:它们指定了该类对象的内部表示 ;
2) 成员函数:它们指定该类的操作;
类成员有3种不同的访问权限:
1.public: 既可以被本类中的成员函数访问,也可以被类的作用域内的其他函数访问;
2.private: 只能被该类的成员函数访问,类外的其他函数则不能;
3.protected:只能被该类的成员函数和派生类的成员函数访问。
不指定就默认私有。
2.对象的定义和使用
对象是类的实例,对象属于某个已知的类。在定义对象之前,一定要定义好类。对象定义格式为:
<类名><对象名表>
例:
Cdata data1,data2, *Pdata,data[3];
对象的成员格式:
<对象名>.<成员名>(<参数表>)
#include <iostream>
using namespace std;
//下面为类的声明部分
class Carea
{
private:
int x, y; //声明两个私有变量x和y
public:
void set_values (int a,int b); //声明设置矩形长宽值的函数,用来为私有变量赋值
int area(); //声明计算面积的成员函数
};
//下面为矩形面积类的实现部分
void Carea::set_values (int a, int b)
{ //设置长宽值,使对象获取数据
x = a; //私有变量x获取数据
y = b; //私有变量y获取数据
}
int Carea::area ()
{
return (x*y); //通过函数值返回面积
}
int main ()
{
Carea rect1, rect2; //声明两个对象rect1和rect2
rect1.set_values (3,4); //为对象rect1的成员函数的参数赋值
rect2.set_values (5,6); //为对象rect2的成员函数的参数赋值
cout << "rect1 area: " << rect1.area() << endl;
cout << "rect2 area: " << rect2.area() << endl;
return 0;
}
3.构造函数
C++中定义了一种特殊的初始化函数,称为构造函数;当对象被调用时,构造函数自动调用;构造函数名字与类名相同,也没有返回类型和返回值;对象在生成过程中通常需要初始化变量或分配动态内存,用构造函数。
#include <iostream>using namespace std;class carea{private:int length;int width;public:carea(int a, int b);//构造函数声明int area();//计算面积的成员函数的声明};
//以下为构造函数的定义carea :: carea(int a, int b){length = a;width = b;}int carea :: area(){return length*width;}int main(){carea ar1(30, 20); //创建rect1对象并调用构造函数进行初始化cout<<ar1.area()<<endl;return 0;}
还有一种情况,构造函数是可以重载的。那么当构造函数重载是什么情况,请看代码。
#include <iostream>using namespace std;class student{private:char *m_name;int m_age;float m_score;public:student(); //这里就是构造函数的重载student(char *name, int age, float score);void setdata(char *name, int age, float score);void show();};student :: student():m_name(NULL), m_age(0), m_score(0){} //构造函数什么都不做 只是对于公开的数据进行了复赋值。/*{m_name = NULL; //C++结构函数的初始化列表。m_age = 0;m_score = 0;}*/student :: student(char *name, int age, float score):m_name(name), m_age(age), m_score(score){}/*{m_name = name; //C++结构函数的初始化列表。m_age = age;m_score = score;}*/void student :: setdata(char *name, int age, float score){m_name = name;m_age = age;m_score = score;}void student :: show(){cout<<m_name<<" "<<m_age<<" "<<m_score<<endl;}int main(){student stu1("xiangming", 19, 59.8); //调用重载的构造函数的时候,用的是与之参数对应的构造函数stu1.show();student stu2;//student stu2();在有的比较新的编译器中,这样写也是正确的。stu2.setdata("xiangwang", 20, 56.6);stu2.show();student *ptr1 = new student("xiaoliu", 19, 66.6);ptr1->show();student *ptr2 = new student;//调用重载的构造函数的时候,用的是与之参数对应的构造函数ptr2->setdata("xiaotang", 22, 99.9);ptr2->show();delete ptr1;delete ptr2;return 0;}
4.c++中构造函数的初始化列表
在初始的时候,可以对所有的参数进行初始化,当然也可以对一部分参数进行初始化。student :: student (char *name, int age, float score):m_name(name), m_age(age), m_score(score){}student :: student (char *name, int age, float score):m_name(name), m_age(age){,m_score = score;}
这两种都是可以的。
注意点:在初始化列表中要注意赋值的先后顺序。如果不小心则会造成错误。看下面的demo
class demo{private:int m_a;int m_b;public:demo(int b);void show();};demo :: demo(int b):m_a(b), m_b(m_a){}void demo :: show(){cout<<m_a<<","<<m_b<<endl;}int main(){demo obj(100);obj.show();return 0;}
如果这里的demo :: demo(int b):m_a(b), m_b(m_a){}写成demo :: demo(int b):m_b(b), m_a(m_b){}这样的话,就错了。 运行结果如下 [root@localhost 0711]# ./a.out
9077696,100 其中会有一个值会变成垃圾值。
5.析构函数
析构函数,是在对象被删除前由系统自动执行它作清理工作。看代码#include <iostream>using namespace std;class carea{private:int *width;int *height;public:carea(int a, int b);~carea();int area();};carea :: carea(int a, int b){width = new int;height = new int;*width = a;*height = b;}carea :: ~carea(){delete width; //释放指针变量width占用的内存资源delete height; //释放指针变量height占用的内存资源cout<<"set free"<<endl; //调用析构函数的信息提示}int carea :: area(){return ((*width) * (*height));}int main(){carea are1(3, 4), are2(5, 6);cout<<"1 area"<<are1.area()<<endl;cout<<"2 area"<<are2.area()<<endl; //在程序运行完之前,析构函数自动执行。return 0;}
析构函数调用顺序
#include <iostream>using namespace std; //是指标准库中输入输出流的头文件, cout就定义在这个头文件里class Test //定义类{private: //私有变量int num;public:Test(int a) //定义构造函数{num = a;cout<<"第"<<num<<"个Test对象的构造函数被调用"<<endl;}~Test()//定义析构函数{cout<<"第"<<num<<"个Test对象的析构函数被调用"<<endl; }};int main(){cout<<"进入main()函数"<<endl;Test t[4] = {0,1,2,3};//定义4个对象,分别以0、1、2、3赋给构造函数的形参acout<<"main()函数在运行中"<<endl;cout<<"退出main()函数"<<endl;return 0;}
6.查看类和对象的大小
直接看demo#include <iostream>using namespace std;class student{private:char *m_name;int m_age;float m_score;public:void setname(char *name){m_name = name;}void setage(int age){m_age = age;}void setscore(float score){m_score = score;}void show(){cout<<m_name<<","<<m_age<<","<<m_score<<endl;}};int main(){student *ptr = new student;cout<<sizeof(ptr)<<endl;cout<<sizeof(*ptr)<<endl;cout<<sizeof(student)<<endl;ptr->show();return 0;}
运行结果: 4 12 12