首先看一段代码
#include<iostream>
using namespace std;
int car_num=0;
struct position {
double x, y;
};
class CarBody {
private:
position a, b, c, d;
public:
position Geta() { return a; }
position Getb() { return b; }
position Getc() { return c; }
position Getd() { return d; }
CarBody(position _a = { -1,1 }, position _b = { 1,1 }, position _c = { 1,-1 }, position _d = { -1,-1 })
:a(_a), b(_b), c(_c), d(_d){}
CarBody(CarBody &car):a(car.Geta()), b(car.Getb()), c(car.Getc()), d(car.Getd()) {}
~CarBody(){}
};
class CarTyre {
private:
position O1, O2;
double R1, R2;
public:
position GetO1() { return O1; }
position GetO2() { return O2; }
double GetR1() { return R1; }
double GetR2() { return R2; }
CarTyre(position _O1 = { -0.5,-1.5 }, double _R1 = 0.5, position _O2 = { 0.5,-1.5 }, double _R2 = 0.5)
:O1(_O1), O2(_O2), R1(_R1), R2(_R2) {}
CarTyre(CarTyre& t) :O1(t.GetO1()), O2(t.GetO2()), R1(t.GetR1()), R2(t.GetR2()) {}
~CarTyre(){}
};
class Car {
private:
CarBody body;
CarTyre tyre;
public:
CarBody GetBody() { return body; }
CarTyre GetTyre() { return tyre; }
Car(CarBody _body, CarTyre _tyre) :body(_body), tyre(_tyre) { car_num++; } //利用两个新类可以实现对Car类的构造
Car(Car& n) :body(n.GetBody()), tyre(n.GetTyre()) { car_num++; }
~Car() { car_num--; cout << "剩下" << car_num << "辆车" << endl; }
};
int main() {
CarTyre t({ -1,-2 },1.0, { 1,-2 }, 1.0);
CarBody b({ -2,1 }, { 2,1 }, { 2,-1 }, { -2,-1 });
Car c(b, t);
Car c2(b, t);
Car c3(b, t);
Car c4(b, t);
cout << car_num<<endl;
return 0;
}
当我们编译这段代码时,编译器会在Car类的复制构造函数处报错,提示:“对象包含与成员函数不兼容的类型限定符”,这是我们在嵌套的类的复制构造函数中没有使用const导致的,所以只需要将两个嵌套类的复制构造函数参数变为const类型的即可:
#include<iostream>
using namespace std;
int car_num=0;
struct position {
double x, y;
};
class CarBody {
private:
position a, b, c, d;
public:
position Geta() { return a; }
position Getb() { return b; }
position Getc() { return c; }
position Getd() { return d; }
CarBody(position _a = { -1,1 }, position _b = { 1,1 }, position _c = { 1,-1 }, position _d = { -1,-1 })
:a(_a), b(_b), c(_c), d(_d){}
CarBody(const CarBody &car):a(car.Geta()),b(car.Getb()),c(car.Getc()),d(car.Getd()){}
~CarBody(){}
};
class CarTyre {
private:
position O1, O2;
double R1, R2;
public:
position GetO1() { return O1; }
position GetO2() { return O2; }
double GetR1() { return R1; }
double GetR2() { return R2; }
CarTyre(position _O1 = { -0.5,-1.5 }, double _R1 = 0.5, position _O2 = { 0.5,-1.5 }, double _R2 = 0.5)
:O1(_O1), O2(_O2), R1(_R1), R2(_R2) {}
CarTyre(const CarTyre& t):O1(t.GetO1()),O2(t.GetO2()),R1(t.GetR1()),R2(t.GetR2()) {}
~CarTyre(){}
};
class Car {
private:
CarBody body;
CarTyre tyre;
public:
CarBody GetBody() { return body; }
CarTyre GetTyre() { return tyre; }
Car(CarBody _body, CarTyre _tyre) :body(_body), tyre(_tyre) { car_num++; } //利用两个新类可以实现对Car类的构造
Car(Car& n) :body(n.GetBody()), tyre(n.GetTyre()) { car_num++; }
~Car() { car_num--; cout << "剩下" << car_num << "辆车" << endl; }
};
int main() {
CarTyre t({ -1,-2 },1.0, { 1,-2 }, 1.0);
CarBody b({ -2,1 }, { 2,1 }, { 2,-1 }, { -2,-1 });
Car c(b, t);
Car c2(b, t);
Car c3(b, t);
Car c4(b, t);
cout << car_num<<endl;
return 0;
}
但这时编译器又会报错:“对象含有与成员 函数 “CarBody::Geta” 不兼容的类型限定符”,这是由于形参变为const类之后只能调用const类型的函数,不能调用原来定义的non_const类型的函数;
要解决此问题,我们只需在Get函数中加入const即可,具体方法如下:
#include<iostream>
using namespace std;
int car_num=0;
struct position {
double x, y;
};
class CarBody {
private:
position a, b, c, d;
public:
position Geta()const { return a; }
position Getb()const { return b; }
position Getc()const { return c; }
position Getd()const { return d; }
CarBody(position _a = { -1,1 }, position _b = { 1,1 }, position _c = { 1,-1 }, position _d = { -1,-1 })
:a(_a), b(_b), c(_c), d(_d){}
CarBody(const CarBody &car):a(car.Geta()),b(car.Getb()),c(car.Getc()),d(car.Getd()) {}
CarBody(CarBody &car):a(car.Geta()), b(car.Getb()), c(car.Getc()), d(car.Getd()) {}
~CarBody(){}
};
class CarTyre {
private:
position O1, O2;
double R1, R2;
public:
position GetO1()const { return O1; }
position GetO2()const { return O2; }
double GetR1()const { return R1; }
double GetR2()const { return R2; }
CarTyre(position _O1 = { -0.5,-1.5 }, double _R1 = 0.5, position _O2 = { 0.5,-1.5 }, double _R2 = 0.5)
:O1(_O1), O2(_O2), R1(_R1), R2(_R2) {}
CarTyre(const CarTyre& t):O1(t.GetO1()),O2(t.GetO2()),R1(t.GetR1()),R2(t.GetR2()) {}
CarTyre(CarTyre& t) :O1(t.GetO1()), O2(t.GetO2()), R1(t.GetR1()), R2(t.GetR2()) {}
~CarTyre(){}
};
class Car {
private:
CarBody body;
CarTyre tyre;
public:
CarBody GetBody() { return body; }
CarTyre GetTyre() { return tyre; }
Car(CarBody _body, CarTyre _tyre) :body(_body), tyre(_tyre) { car_num++; } //利用两个新类可以实现对Car类的构造
Car(Car& n) :body(n.GetBody()), tyre(n.GetTyre()) { car_num++; }
~Car() { car_num--; cout << "剩下" << car_num << "辆车" << endl; }
};
int main() {
CarTyre t({ -1,-2 },1.0, { 1,-2 }, 1.0);
CarBody b({ -2,1 }, { 2,1 }, { 2,-1 }, { -2,-1 });
Car c(b, t);
Car c2(b, t);
Car c3(b, t);
Car c4(b, t);
cout << car_num<<endl;
return 0;
}
const类型的类只能调用const类型的成员函数,原因是防止non_const类型的函数对其造成修改。(注:const类型与non_const类型的函数可以实现重载)
如果想在const类型的函数中进行变量的修改,可在变量定义时在变量之前加上mutable。