过去的四章内容由于考试,导致进度偏慢,书中内容还剩下运算符重载、继承与派生、多态与虚函数、I/O流、文件的操作以及泛型编程与STL六个部分,争取一个礼拜能够完成一章的学习与总结练习,能在2018年到来之前将C++的基础概念性东西打扎实基础;方便后续学习。
常量对象与常量成员函数
常量的目的就是不允许外界修改。如果希望某个对象在初始化之后就不再改变,则可以定义常量对象。常量对象的写法为:const 类名 对象;既然不希望被改变,那么调用的函数也只能带const。常量成员函数的作用就是为常量成员所调用。常量成员函数的定义形式为:函数名(参数表)const{函数体}注意const写在参数表的后部。
一个小小的例子说明下常量对象与常量成员函数的使用
#include<iostream>
using namespace std;
class CTyre {
int r;
public:
CTyre();
CTyre(int i);
void print() {
cout << "the radius is " << r<<"mm"<<endl;
}
void printr()const {
cout << "haha" << endl;
}
static void printrr() {
cout << "let me see" << endl;
}
};
CTyre::CTyre() {
r = 0;
}
CTyre::CTyre(int i) {
r = i;
}
int main() {
const CTyre t1;
//t1.print();
t1.printr();
t1.printrr();
return 0;
}
如程序所示,该程序定义了一个CTyre轮胎类,轮胎类内包含构造函数CTyre(),类型转换构造函数,一个普通print()函数,一个printr()常量成员函数。在main函数中首先定义了一个常量成员t1,然后依次调用不同的打印函数进行打印,然而t1.print()将会报错,这是因为常量成员不能调用非常量成员函数(静态成员函数除外,因为静态成员函数为所有类所共有)。t1.printr()与t1.printrr()则正常打印输出。
因此常量对象可以调用1,常量成员函数以及2,静态成员函数。
成员对象和封闭类
封闭类:A类的内部包含有其他类(例如B类,C类对象)则称A类为封闭类
成员对象:上述中B、C类的对象则为成员对象。
初始化
封闭类通过初始化列表初始化内部参数,形式同于普通类的初始化列表---在后面跟上一长串变量以及参数表
初始化列表如下
类名::构造函数名(参数表):成员变量1(参数表),成员变量2(参数表),...
{
...
}
#include<iostream>
using namespace std;
class CTyre {
private:
int radius;
int width;
public:
CTyre(int r,int w):radius(r),width(w){}
};
class CEngine {
};
class CCar {
private:
int price;
CTyre tyre;
CEngine engine;
public:
CCar(int p, int tr, int tw);
};
CCar::CCar(int p, int tr, int tw) :price(p), tyre(tr, tw) {
};
int main() {
CCar car(20000, 17, 35);
return 0;
}
该段程序包含三个类:汽车类CCar,轮胎类CTyre以及引擎类CEngine,CTyre类初始化时,通过初始化列表CTyre(int r,int w):radius(r),width(w)进行。而汽车类CCar内部包含轮胎类及引擎类两个子类。类似于普通构造,则该函数构造如上述程序所示。
#include<iostream>
using namespace std;
class CTyre {
private:
int radius;
int width;
public:
CTyre(int r,int w):radius(r),width(w){
cout << "CTyre constructor called" << endl;
}
~CTyre() {
cout << "CTyre deconstructor called" << endl;
}
};
class CEngine {
public:
CEngine() {
cout<< "CEngine constructor called" << endl;
}
~CEngine() {
cout << "CEngine deconstructor called" << endl;
}
};
class CCar {
private:
int price;
CTyre tyre;
CEngine engine;
public:
CCar(int p, int tr, int tw);
~CCar();
};
CCar::CCar(int p, int tr, int tw) :price(p), tyre(tr, tw) {
cout<< "CCar constructor called" << endl;
};
CCar::~CCar() {
cout<< "CCar deconstructor called" << endl;
}
int main() {
CCar car(20000, 17, 35);
return 0;
}
在施行函数构造时,先执行所有成员对象的构造函数,最后实现封闭类的构造函数。其原因是:只有明确每个调用的内部成员的对象是什么样的时候,才能知道这个封闭类长什么样。而析构时恰好相反:先执行封闭类的析构函数,再执行成员对象的析构函数。就和剥洋葱一样,先得把外面的壳给剥掉,才能剥掉里面的。简而言之就是由小到大逐步构造打基础,由外到内析构剥洋葱。
封闭类的复制构造函数
封闭类的对象,如果是用复制构造函数初始化的,那么它里面包含的成员对象也会用复制构造函数初始化。
零散的概念:const及引用成员和友元
除了可以有常量对象及常量成员函数以外,还可以有常量成员,其方法即是在成员前面直接加上const关键字,常量成员变量的值一旦初始化则不能再改变。
友元的作用则是放开一定的程序封装性,允许外界调用一下类内封装为私有的成员变量或者成员函数。其形式在于在类内的函数前面加friend关键字,表示这个类有了这个朋友friend。而友元又分为友元函数以及友元类;友元函数表示有一个函数是我们这个类的朋友,友元类表明有了一个类作为朋友。
this指针
this指针的作用是指向成员函数作用的对象,也就是现在作用于谁,this指针就默认的指向谁
#include<iostream>
using namespace std;
class Complex {
public:
double real, imag;
Complex(double r, double i) :real(r), imag(i) {
}
Complex Addone() {
this->real++;
return *this;
}
};
int main() {
Complex c1(1, 1), c2(0, 0);
c2 = c1.Addone();
cout << c2.real << "," << c2.imag << endl;
return 0;
}