(八)继承二
2016.6.28
三、把子类对象当做父类对象使用
void func(Point &p){
p.print();
}
Point& func1(Circle& c ){
return c;
}
void func2(Point *pp){
pp->print();
}
Point* func3(){
Circle *c=new Circle(10,20,30);
return c;
}
void func4(Point p){//调用父类的拷贝构造函数(Point p=c)
}
Point func5(){
Circle c(36,48,54);
return c;//创建一个临时对象(父类对象)
}
int main(){
Point p(10,20);
p.print();
Circle ci(2,5,9);
cout<<"radius="<<ci.getr()<<endl;
cout<<"area="<<ci.getArea()<<endl;
cout<<"pare="<<ci.getPare()<<endl;
ci.print();
cylinder cl(4,5,6,10);
cl.printcl();
cout<<"volum="<<cl.Volum()<<endl;
cout<<"cpare="<<cl.cPare()<<endl;
/*
子类对象当成父类对象使用
1、子类对象直接赋值给父类对象,
2、父类引用指向子类对象:
(**子类对象初始化父类引用)
(**函数形参是一个父类引用、实参是一个子类对象)
(**函数原型返回值为父类引用、但返回值为一个子类对象)
3、父类指针指向子类对象
(**子类对象初始化父类指针)
(**函数形参是一个父类指针,实参是一个子类对象)
(**函数原型返回值是父类指针,但返回值为一个子类对象地址)
4、拷贝构造函数
**使用子类对象直接创建父类对象
**函数形参是一个父类对象,实参是一个子类对象
**函数原型返回值是父类对象,但返回值是子类对象
子类对象赋值给父类对象、引用、指针、父类对象,不能调用子类扩展的成员函数
**子类对象可以当成父类使用,但是父类不能当成子类使用
类型转换:
Point *pp=&c1;
// pp->getr();父类指针不能调用子类扩展成员函数
((Circle*)pp)->getr(); //强制转换:向下转换(不被使用、不安全,编译器不能确定转换类型是否成功)->dynamic_cast<>()
*/
//子类对象直接赋值给父亲对象
Point p2=ci;
p2.print(); //父类的print函数
//b.getr(); 父类对象亦可以调用子类扩展函数
Point& p4=p2;
Point& p3=ci; //子类对象初始化父类引用
p3.print(); //父类函数被调用
// p3.getr();父类引用指向子类对象,不能调用子类扩展函数
func(cl); //调用函数,参数为子类对象
Circle c1(100,200,2);
func1(c1).print(); //函数原型返回值为父类引用、但返回值为一个子类对象
Point *pp=&c1; //子类对象初始化父类指针
pp->print();
// pp->getr();父类指针不能调用子类扩展成员函数
((Circle*)pp)->getr(); //强制转换:向下转换(不被使用、不安全,编译器不能确定转换类型是否成功)->dynamic_cast<>()
Circle c2(34,45,67);
func2(&c2); //函数形参是一个父类指针,实参是一个子类对象
func3()->print(); //函数原型返回值是父类指针,但返回值为一个子类对象地址
Point p5(40,50);
Circle c3(12,23,34);
Point p6(p5);//
Point p7(c3);//
cout<<"============="<<endl;
func4(c3); //调用父类的拷贝构造函数
cout<<"============="<<endl;
func5().print();
}
四、子类中的构造函数、析构函数、和赋值运算符重载函数
1.构造:先调用父类的构造函数,在调用子类的构造函数。
2.析构:先调用子类析构函数,来释放扩展的指针堆k空间,再自动调用父类析构函数,来释放继承父类部分指针放的堆空间。
所以子类只需要释放自己扩展部分的对空间。继承部分默认由父类完成。
3.拷贝构造函数:先调用父类的拷贝构造函数(把继承自父类部分先进行复制),再完成子类扩展部分内容的赋值。
#include <iostream>
using namespace std;
class MyPoint{
friend ostream& operator<<(ostream & out,const MyPoint& mp){
out<<"x="<<mp.x<<endl;
out<<"y="<<mp.y<<endl;
return out ;
}
public:
MyPoint():x(0),y(0){}
MyPoint(int _x,int _y):x(_x),y(_y){}
void print(){
cout<<"x="<<x<<endl;
cout <<"y="<<y<<endl;
}
protected:
int x;
int y;
};
class myCiecle:public MyPoint{
friend ostream& operator<<(ostream & out,const myCiecle& c){
out<<c.x<<endl;
out<<c.y<<endl;
out<<c.r<<endl;
out<<"=================="<<endl;
return out;
}
protected:
int r;
public:
myCiecle():MyPoint(),r(0){}
myCiecle(int _x,int _y,int _r):MyPoint(_x,_y),r(_r){}
public:
int Area(){
return 3*r*r;
}
void print(){
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
cout<<"r="<<r<<endl;
}
};
class Mycylinder:public myCiecle{
friend ostream& operator<<(ostream & out,const Mycylinder& cy){
out<<cy.x<<endl;
out<<cy.y<<endl;
out<<cy.r<<endl;
//out<<cy.h<<endl;
return out;
}
};
int main(int argc, const char * argv[]) {
MyPoint p(2,3);
cout<<"p=\n"<<p<<endl;
MyPoint pp(0,0);
cout<<"pp=\n"<<pp<<endl;
pp=p; //同类型对象赋值
cout<<"pp=\n"<<pp<<endl;
myCiecle c(5,6,7);
pp=c; //子类对象当成父类对象使用
cout<<"pp=\n"<<pp<<endl;
pp=(MyPoint)c; //向上转型,安全
cout<<"pp=\n"<<pp<<endl;
// c=(myCiecle)pp; //父类对象不能转换成子类对象
//c=pp; //父类对象不能当做子类使用
MyPoint* pPoint;
pPoint=&c; //父类指针指向子类对象
pPoint->print(); //父类函数被调用
//向下转换
cout<<"_________________________"<<endl;
((myCiecle*)pPoint)->print();
//myCiecle* pc=&pp; //不可以
MyPoint& r=c;//父类引用指向子类对象
r.print();//父类print()
return 0;
}