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 0 != 0)) || (year @0 == 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赋给构造函数的形参a
cout<<"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