一、类和对象的基本概念
c程序是结构化程序设计,程序量大了以后,容易搞不清哪个函数操作哪个变量,没有封装和隐藏的概念
使用方法
1. 对象名.成员名
CRectangle r1,r2;
r1.w = 5;
r2.Init(5,4);
2.指针->成员名
CRectangle r1,r2;
CRectangle * p1 = & r1;
Crectangle * p2 = & r2;
p1->w = 5;
p2->Init(5,4);
3.引用名.成员名
rr变了,r1也会变。
CRectangle r1;
CRectangle & rr = r1;
rr.w = 5;
rr.Init(5,4);
类的成员函数和类的定义可以分开写
class CRectangle
{
public:
int w,h;
int Area(); //此处仅是声明
}
int CRectangle::Area(){
return w*h
}
类的函数可以直接调用成员变量,而无需将其作为形参传进去
类成员的可被访问范围
-private: 如果没有说明,缺省为私有成员
-pubile:
-protected:
在类的成员函数以外的地方,只能访问该类对象的共有成员
二、构造函数
成员函数的一种,名字与类名相同,可以有参数,不能有返回值
作用:对对象进行初始化,如 给成员变量赋初值
注意:
-对象生成时会自动调用构造函数,不用担心没有调用初始化函数
-一旦生成,就再也不能再其上执行构造函数
-一个类可以有多个构造函数,参数类型或个数不同,就可有重载
-如果没有编写构造函数,编译器自动生成默认无参构造函数
构造函数在数组中的使用:
class Test{
public:
Test(int n){} //(1)
Test(int n,int m){} //(2)
Test(){} //(3)
};
Test array1[3] = {1,Test(1,2)};
//arrary1[1]使用 (1) 初始化
//arrary1[2]使用 (2) 初始化
//arrary1[3]使用 (3) 初始化
指针数组和对象数组
指针数组的每一个元素都是指针
复制构造函数
复制构造函数是干嘛的?实现两个对象之间的复制
只有一个参数,即对同类对象的引用,复制构造函数一定存在,编译器自动生成,无参构造函数不一定存在
形如:X::X( X&) 或者 X::X(const X &),后者能以常量对象作为参数,参数必须是引用,不能是直接把对象拿过来
class Complex{
private:
double real,imag;
};
Complex c1; //调用缺省的无参构造函数,创建对象
Complex c2(c1); //调用缺省的复制构造函数,将c2初始化成和C1一样
Complex c2 = c1; //与上式等价
//如果:
Complex c1,c2;
c2 = c1 ; //这是赋值,并不是初始化,不会调用复制构造函数
如果再某个函数有一个形参是类A的对象,那么该函数被调用的时候,是用类A的复制构造函数完成的:
void Func(A a1){}
in main(){
A a2;
Func(a2);
return 0;
}
//以上过程会调用A的复制构造函数,如果不想有此开销,可对Func作如下定义:
void Func(A & a){}
//但是这就可能会使传入的实参对象,在函数中被改变,如果不想,可以加const
定义的复制构造函数可以不做复制工作,此时形参未必是实参的拷贝,用处尚不明确????
类型转换构造函数
析构函数
~类名(),在对象消亡时自动调用,可以在其中定义空间释放等操作
当 对象 作为函数返回值的时候,形参对象会被析构,然后创建一个临时对象返回,语句结束后,临时对象也会被析构。
静态局部变量,在全部结束后,才会消亡(const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间。)
- const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数
- static静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的外部,通常在类的实现文件中初始化
- static就是下次调用的时候,这个值保持不变
new出来的东西,一定要delete才会消亡