C++学习之类和对象巩固
-
类成员的可访问范围
private:私有成员,只能在成员函数内访问。
public:公有成员,可以在任何地方访问。
在类的成员函数内部,能够访问1、当前对象的全部属性和函数;2、同类其他对象的全部属性和函数。
在类的成员函数以外的地方,只能够访问该类对象的公有成员。
设置成员函数的机制,叫做隐藏,
“隐藏”的目的是强制对成员变量的访问一定要通过成员函数 进行,那么以后成员变量的类型等属性修改后,只需要更改成员函数即可。否则,所有直接访问成员变量的语句都需要修改。
struct与class最大的区别就是class中的成员均为公有成员。
-
成员函数的重载和参数缺省
上面一段程序的输出是5.
使用缺省参数时要注意避免有函数重载的二义性,如:
-
构造函数(constructor)
成员函数的一种,名字与类名相同,可以有参数,不能有返回值(void也不行)。
作用是对对象进行初始化,如给成员变量赋初值。
定义时没写构造函数时编译器会生成一个默认的无参数的构造函数。默认构造函数不做任何操作。
如果定义了构造函数则编译器不生成默认构造函数。
对象生成时构造函数自动被调用,对象一旦生成就再也不能在其上执行构造函数。
一个类可以有多个构造函数。
构造函数最好是public的,private的构造函数不能直接用来初始化对象。
构造函数在数组中的使用:
上面程序的输出为:
例题:
因为上面的语句只是生成了没有指向的指针,不属于对象,所以只调用了两次构造函数。
当生成的指针数组中的指针指向NULL时,也没有生成对象。
-
复制构造函数(copy constructor)
只有一个参数,即对同类对象的引用。
形如X::X(X&)或X::X(const X&)后者以常量对象作为参数。
如果没有定义复制构造函数,那么编译器生成默认的复制构造函数,默认的复制构造函数完成复制功能。
如果定义的是自己的复制构造函数,则默认的复制构造函数不存在。
复制构造函数起作用的三种情况:
1、当用一个对象去初始化同类的另一个对象时。
例如:Complex c2(c1);
Complex c2 = c1; //初始化语句,不是赋值语句。
2、如果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用。
3、如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用。
输出结果为:
Copy constructor called
4
对象间赋值并不导致复制构造函数的调用。
-
常量引用参数的使用
这样的函数,调用时生成形参会引发复制构造函数调用,开销比较大;
所以可以考虑使用CMyclass &引用类型作为参数;
如果希望确保实参的值在函数中不应被改变,那么可以加上const关键字;
-
类型转换构造函数
目的是实现类型的自动转换;
只有一个参数而且不是复制构造函数的构造函数,一般就可以看做转换构造函数。
当需要的时候,编译系统会自动调用转换构造函数,建立一个无名的临时对象(或临时变量)
-
析构函数
名字与类名相同,前面加~,没有参数和返回值,一个类最多只能有一个析构函数。
析构函数对象消亡时即自动被调用。可以定义析构函数来在对象消亡前做善后工作,比如释放分配的内存。
如果定义类时没写析构函数,则编译器生成缺省析构函数,缺省析构函数什么也不做。
如果定义了析构函数,则编译器不生成缺省析构函数。
对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用。
例题:
假如A是一个类的名字,下面的程序片段会调用类A的析构函数几次?
int main() {
A * p = new A[2];
A * p2 = new A;
A a;
delete [] p;
}
正确答案:3次。因为对象a在结束时会自动调用析构函数,而new生成的p2则不会。