在C++中,只要原来的返回类型是指向类的指针或引用,新的返回类型是指向派生类的指针或引用,覆盖的方法就可以改变返回类型。这样的类型称为协变返回类型(Covariant returns type).
返回类型协变
覆盖要求函数具有完全相同的入参。
一般覆盖具有相同的返回值,否则会提示错误
virtual double area ()const = 0;
virtual float area ()const ; //编译器提示错误,返回类型不同
这个规则对返回类型协变而言,则有所放松。覆盖的返回值不区分基类或派生类。从语意上理解,一个派生类也是一个基类。如下:
Class ShapeEditor ...{……};
Class Shape
...{
public:
virtual const ShapeEditor & getEditor ()const = 0; //Factory Method
};
Class Circle;
Class CircleEditor : public ShapeEditor...{ … };
Class Circle : Public Shape
...{
public:
const CircleEditor &getEditor ()const ;
};
在这个例子中,注意 CircleEditor必须在Circle::getEditor的声明之前被完整地定义(而不能仅仅声明),
因为编译器必须知道 CircleEditor对象的布局,才能执行适当的地址操纵,从而将一个CircleEditor引用
(或指针)转换为一个ShapeEditor引用(或指针)。
协变返回类型的优势在于,总是可以在适当程度的抽象层面工作。若我们是处理Shape,将获得一个抽象的ShapeEditor;若正在处理某种具体的形状类型,比如Circle,我们就可以直接获得CiecleEditor.协变返回机制将我们从这样的一种处境解脱出来:不得不使用易于出错的转换操作来“重新”提供类型信息,而这种信息是一开始就不应该丢掉的:(那么,对于友元,派生的operator+,怎么样调用基类的operator+呢?)
Shape * s =getACircleOrOtherShape ();
Const ShapeEditor &sed =s->getEditor();
Ciecle *c =getACircle();
Const CircleEditor &ced =c->getEditor();
const用在成员函数后
#include<iostream>
using namespace std;
class Text
{
public:
Text(int i):k(i){}
void printconst(void)const{cout<<"hello"<<endl;}
void print(void){cout<<"hello"<<endl;}
private:
int k;
};
//上面定义了类Text的一常量对象
int main(void)
{
const Text a(1);
a.printconst(); //ok
a.print(); //error
//上面a.print()调用是非法的
return 0;
}
D:\VCWorking\GCCSample\ConstFuc.cpp:18:11: error: passing 'const Text' as 'this' argument of 'void Text::print()' discards qualifiers
const对象只能调用const成员函数。 const对象的值不能被修改,在const成员函数中修改const对象数据成员的值是语法错误
在const函数中调用非const成员函数是语法错误
这是把整个函数修饰为const,意思是“函数体内不能对成员数据做任何改动”。如果你声明这个类的一个const实例,那么它就只能调用有const修饰的函数。
常成员函数
#include <iostream>
using namespace std;
class R
{
public:
R(int r1, int r2) { R1=r1; R2=r2; }
void print();
void print() const;
private:
int R1, R2;
};
void R::print()
{
cout<<R1<<R2<<endl;
}
void R::print() const
{
cout<<R1<<R2<<endl;
}
int main()
{
R a(5, 4);
a.print();
const R b(20, 52);
b.print();
return 1;
}
5,4
20;52