1、面向对象的程序设计具有四个基本特点
- 抽象
- 封装
- 继承
- 多态
2、使用类的成员变量和成员函数
- 对象名.成员名
- 指针->成员名
- 引用名.成员名
CRectangle r1,r2;
r1.w = 1; //第一种方式
CRectangle * p1 = & r1;
p1->w = 2; //第二种方式
CRectangle & rr = r2;
rr.w = 3; //第三种方式
3、类成员的可访问范围
(1)在类的定义中,用下列访问范围关键字来说明类成员可被访问的范围:
- private: 私有成员,只能在成员函数内访问
- public : 公有成员,可以在任何地方访问
- protected: 保护成员,继承类可以访问
(2)定义一个类:
class className {
private:
私有属性和函数
public:
公有属性和函数
protected:
保护属性和函数
};
(3)如过某个成员前面没有上述关键字,则缺省地被认为是私有成员
4、构造函数(constructor)
(1)特点:
- 名字与类名相同,可以有参数,不能有返回值(void也不行)
- 作用是对对象进行初始化,如给成员变量赋初值
- 如果定义类时没写构造函数,则编译器生成一个默认的无参数的构造函数,默认构造函数无参数,不做任何操作
- 如果定义了构造函数,则编译器不生成默认的无参数的构造函数
- 对象生成时构造函数自动被调用。对象一旦生成,就再也不能在其上执行构造函数
- 一个类可以有多个构造函数
(2)构造函数在数组中的使用
class CSample {
int x;
public:
CSample() {
cout << "Constructor 1 Called" << endl;
}
CSample(int n) {
x = n;
cout << "Constructor 2 Called" << endl;
}
};
int main(){ //输出:
CSample array1[2]; //Constructor 1 Called
cout << "step1"<<endl; //Constructor 1 Called
CSample array2[2] = {4,5}; //step1
cout << "step2"<<endl; //Constructor 2 Called
CSample array3[2] = {3}; //Constructor 2 Called
cout << "step3"<<endl; //step2
CSample * array4 = //Constructor 2 Called
new CSample[2]; //Constructor 1 Called
delete []array4; //step3
return 0; //Constructor 1 Called
} //Constructor 1 Called
5、复制构造函数(copy constructor)
扫描二维码关注公众号,回复:
2621741 查看本文章
(1)特点:
- 只有一个参数,即对同类对象的引用。形如 X::X( X& )或X::X(const X &), 二者选一,后者能以常量对象作为参数
- 如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。
- 如果定义的自己的复制构造函数,则默认的复制构造函数不存在。
- 不允许有形如 X::X( X )的构造函数。
class Complex {
public :
double real,imag;
Complex(){ }
Complex( const Complex & c ) {
real = c.real;
imag = c.imag;
cout << “Copy Constructor called”;
}
};
Complex c1;
Complex c2(c1);//调用自己定义的复制构造函数,输出 Copy Constructor called
(2)复制构造函数起作用的三种情况:
- 当用一个对象去初始化同类的另一个对象时
- 如果某函数有一个参数是类 A 的对象,那么该函数被调用时,类A的复制构造函数将被调用
- 如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用
6、析构函数
(1)特点:
- 名字与类名相同,在前面加‘~’, 没有参数和返回值,一个类最多只能有一个析构函数。
- 析构函数对象消亡时即自动被调用。可以定义析构函数来在对象消亡前做善后工作,比如释放分配的空间等。
- 如果定义类时没写析构函数,则编译器生成缺省析构函数。缺省析构函数什么也不做。
- 如果定义了析构函数,则编译器不生成缺省析构函数
(2)析构函数和数组:对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用
class Ctest {
public:
~Ctest() { cout<< "destructor called" << endl; }
};
int main () {
Ctest array[2];
cout << "End Main" << endl;
return 0;
}
输出:
End Main
destructor called
destructor called
(3)析构函数和运算符 delete:delete 运算导致析构函数调用
(4)析构函数在对象作为函数返回值返回后被调用
class CMyclass {
public:
~CMyclass() { cout << "destructor" << endl; }
};
CMyclass obj;
CMyclass fun(CMyclass sobj ) { // 参数对象消亡也会导致析构函数被调用
return sobj; // 函数调用返回时生成临时对象返回
}
int main(){
obj = fun(obj); // 函数调用的返回值(临时对象)被
return 0; // 用过后,该临时对象析构函数被调用
}