1.类的结构如下:
class class_name{ //类名称,用户定义的
public://public成员,任何看到这个类的都可以使用该成员
member1;//可以是函数,也可以是数据
private://只有同一个class的其他成员或者该class的友元/friend class才能访问
member2;
......
protect: //只有同一个class的其他成员或者友元类或者该类的子类可以访问
member3;
}object_name; //一个或者几个对象的标识
class CRectangle{ //CRectangle 是类的名称
int x,y;//若没有定义,则默认为private类型的
public:
void set_value(int ,int )
int area(void)
}rect; //是CRectangle类型的对象的名称
CRectangle 和 rect的关系就像 int 和变量a的对象一样 int(类型名) a(对象名,变量)
如果对象需要调用类里面的函数,则以下
rect.set_value(3,4)
myarea=react.area();
如何在外部定义一个类里面的函数?
class CRectangle{
int x,y; //在这里默认为x,y,虽然现在看不出什么好处,但是在复杂的代码中还是能体现出来的。
public:
void set_values(int a,int b);
int area(void){return x*y}; //与在外部定义函数不同,唯一的区别是类会默认这里为inliner(个人理解应该是内联函数)
}rect;
void CRectangle::set_values(int a,int b) //"::"范围操作符,申明了被定义的成员所属的class名称,并赋予一定的属性,这些属性在类内部的访问权限是一样的
{
x=a;
y=b;
}
int main()
{
CRectangle rect; //实例化,也叫申明了俩个对象,每一个类对象都拥有自己的变量x和y,以及它自己的函数set_value()和area()
CRectangle rectb;//俩个实例,或者说俩个对象,每一个对象都拥有自己的成员变量和成员函数。
rect.set_values(2,3)
cout<< rect.area()<<endl;
cout<<rectb.area()<<endl;
}
2.构造函数和析构函数
a.构造函数
对象在生成过程中需要初始化变量或分配内存(这就好比定义一个int a=3的时候不仅需要初始化同时需要分配内存);
一个class可以包含一个特殊的函数:构造函数(constructor),申明一个与类名称同名的函数来定义。当且仅当实例化也就是明一个对象时,或给class的一个对象分配内存时,这个构造函数将自动被调用(为了分配内存的)
#include <iostream>
using namespace std;
class CRectangle{
int x,y;
public:
// void set_value(int a,int b);
CRectangle( int,int );
int area(void){return (x*y);}
};
CRectangle::CRectangle(int a, int b) //构造函数的原型和实现中都没有返回值(return vaule),也没有void 类型申明。构造函数必须这样子写。构造函数永远没有返回值,也不用void声明
{
x=a;
y=b;
}
int main()
{
CRectangle rect(3,4); //将set_vaule 换成了构造函数进行申明
CRectangle rectb(5,6);
cout<<rect.area()<<'\n'<<endl;
cout<<rectb.area()<<'\n'<<endl;
return 0;
}
b.析构函数
析构函数完成相反的功能,当对象从内存中释放的时候被自动调用,释放可能是因为它存在的范围已经结束了或者是因为它是一个动态分配的对象,而被使用操作符delete释放了。
析构函数必须与class同名,必须无返回值。
#include <iostream>
using namespace std;
class Rectangle
{
int *wigth,*heigth;
public:
Rectangle(int a,int b);
~Rectangle(); //不含任何形参
int area(void){return (*wigth**heigth);}
};
Rectangle::Rectangle(int a,int b)
{
wigth=new int;
heigth=new int;
*wigth=a;
*heigth=b;
}
Rectangle::~Rectangle() //直接调用,没有返回值
{
delete wigth;
delete heigth;
}
int main()
{
Rectangle rect(2,3),rectb(4,5);
cout<<rect.area()<<" "<<rectb.area()<<endl;
}
3.构造函数重载
像其他函数一样,构造函数可以被重载,但是有不同的参数个数和参数类型。编译器会调用与在调用时刻要求的参数类型和个数一样的那个函数(简单来说就是符合的构造函数)。在这里则是调用与类对象被声明时一样的那个构造函数。
实际上,当我们没有定义构造函数时,编译器会自动假设俩个重载的构造函数:默认构造函数和复制构造函数
class example{
public:
int a,b,c;
void mutiply(int n,int m){a=n;b=n;c=m};
}
Empty constructor
它是一个没有任何参数的构造函数,什么也不做:example::example(){}
copy constructor
example::example(const example &rv) //只有一个参数的构造函数,该参数是类的对象,这个函数的功能是将被传入的对象(object)的所有非 静态成员变量的值都复制给自身这个object。简单的说就是,把exmple rect(3,4)中的3,4赋值到类里面的变量。
{
a=rv.a;b=rv.b,c=rv.c;
}
这俩个默认构造函数只有在没有在类中定义构造函数的时候才存在的。
当然也可以进行构造函数的重载
#include <iostream>
using namespace std;
class Rectangle
{
int *wigth,*heigth; //申明指针了,既不是局部变量也不是全局变量,所以不会对其分配内存
public:
Rectangle(); //定义一个参数为空的构造函数
Rectangle(int a,int b);
~Rectangle();
int area(void){return (*wigth**heigth);}
};
Rectangle::Rectangle()
{
wigth=new int;
heigth= new int;
*wigth=5;
*heigth=5;
}
Rectangle::Rectangle(int a,int b)
{
wigth=new int; //动态分配内存
heigth=new int;
*wigth=a;
*heigth=b;
}
Rectangle::~Rectangle()
{
delete wigth;
delete heigth;
}
int main()
{
Rectangle rect(2,3),rectb(4,5);
Rectangle retctb;//因为不需要参数,所以不用写()
cout<<rect.area()<<" "<<rectb.area()<<" "<<retctb.area()<<endl;
}
当我们声明一个新的object的时候,如果不想传入参数,则不需要写括号
4.类的指针
其实类也是可以有指针的,因为类一旦被定义后就成为了一种有效的数据类型,因此定义类的指针的时候,只需要类型 *指针名即可,如:Cexample *prect,是一个指向class CRectangle类型的对象的指针。
#include <iostream>
using namespace std;
class Rectangle
{
int x,y;
public:
void set_value(int a,int b){x=a;y=b;}
int area(void){return (x*y);}
};
int main()
{
Rectangle a,*b,*c;
Rectangle *d=new Rectangle[2]; //这个感觉就好像创建一个Ryuctangle d[2],由于数组名是一个常量指针,d[0]其实就跟*d一样
b=new Rectangle;
c=&a;
a.set_value(1,2);
b->set_value(2,3);
d->set_value(2,3);//d->set_value==*d.set_value==d[0].set_value,因为数组名就是一个指向数组第一个元素的指针
d[1].set_value(4,5);
cout<<"a.area:"<<a.area()<<endl;
cout<<"b->area:"<<b->area()<<endl;
cout<<"c->area:"<<c->area()<<endl;
cout<<"d[0].area:"<<d[0].area()<<endl;
cout<<"d[1].area:"<<d[1].area()<<endl;
return 0;
}
读法:*x:由x指向的 。 x.y:对象x的成员 。(*x).y / x->y : 由x指向的对象的成员y。
x[0]:由x指向的第一个对象 x[1]:由x指向的第二个对象 x[2]:由x指向的第三个对象。
4.由关键字和union定义的类
类不仅可以用class定义,也可以用struct和union定义
基本上struct和class是非常相似的,俩着定义的类的唯一区别在于youclass定义的类的成员默认访问权限为private,而struct为public
union在同一个时间能只能存储一个数据成员而已。