继承与派生是同一过程从不同的角度看
保持已有类的特性而构造新类的过程称为继承
在已有类的基础上新增自己的特性而产生新类的过程称为派生。
被继承的已有类称为基类(或父类)
派生出的新类称为派生类(或子类)
直接参与派生出某类的基类称为直接基类
基类的基类甚至更高层的基类称为间接基类
继承的目的:实现设计与代码的重用。
派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。
语法
class 派生类名:继承方式 基类名 { 成员声明; }
例
class Derived: public Base { public: Derived (); ~Derived (); };
语法
class 派生类名:继承方式1 基类名1,继承方式2 基类名2,... { 成员声明; }
注意:每一个“继承方式”,只用于限制对紧随其后之基类的继承。
例
class Derived: public Base1, private Base2 { public: Derived (); ~Derived (); };
例 公有继承举例
Point.h
#ifndef _POINT_H #define _POINT_H class Point { //基类Point类的定义 public: //公有函数成员 void initPoint(float x = 0, float y = 0){ this->x = x; this->y = y; } void move(float offX, float offY){ x += offX; y += offY; } float getX() const { return x; } float getY() const { return y; } private: //私有数据成员 float x, y; }; #endif //_POINT_H
Rectangle.h
#ifndef _RECTANGLE_H #define _RECTANGLE_H #include "Point.h" class Rectangle: public Point { //派生类定义部分 public: //新增公有函数成员 void initRectangle(float x, float y, float w, float h) { initPoint(x, y); //调用基类公有成员函数 this->w = w; this->h = h; } float getH() const { return h; } float getW() const { return w; } private: //新增私有数据成员 float w, h; }; #endif //_RECTANGLE_H
main.cpp
#include <iostream> #include <cmath> using namespace std; #include “Rectangle.h” int main() { Rectangle rect; //定义Rectangle类的对象 //设置矩形的数据 rect.initRectangle(2, 3, 20, 10); rect.move(3,2); //移动矩形位置 cout << "The data of rect(x,y,w,h): " << endl; //输出矩形的特征参数 cout << rect.getX() <<", " << rect.getY() << ", " << rect.getW() << ", " << rect.getH() << endl; return 0; }
"多继承举例"程序代码有误,请看下面更正的代码:
Point.h
#ifndef _POINT_H #define _POINT_H class Point { //基类Point类的定义 public: //公有函数成员 void initPoint(float x = 0, float y = 0) { this->x = x; this->y = y;} void move(float offX, float offY) { x += offX; y += offY; } float getX() const { return x; } float getY() const { return y; } private: //私有数据成员 float x, y; }; #endif //_POINT_H
Rectangle.h
#ifndef _RECTANGLE_H #define _RECTANGLE_H #include "Point.h" class Rectangle: private Point { //派生类定义部分 public: //新增公有函数成员 void initRectangle(float x, float y, float w, float h) { initPoint(x, y); //调用基类公有成员函数 this->w = w; this->h = h; } void move(float offX, float offY) { Point::move(offX, offY); } float getX() const { return Point::getX(); } float getY() const { return Point::getY(); } float getH() const { return h; } float getW() const { return w; } private: //新增私有数据成员 float w, h; }; #endif //_RECTANGLE_H
main.cpp
#include <iostream> #include <cmath> using namespace std; int main() { Rectangle rect; //定义Rectangle类的对象 rect.initRectangle(2, 3, 20, 10); //设置矩形的数据 rect.move(3,2); //移动矩形位置 cout << "The data of rect(x,y,w,h): " << endl; cout << rect.getX() <<", " //输出矩形的特征参数 << rect.getY() << ", " << rect.getW() << ", " << rect.getH() << endl; return 0; }
class A { protected: int x; }; int main() { A a; a.x = 5;//错误 } class A { protected: int x; }; class B: public A{ public: void function(); }; void B:function() { x = 5; //正确 }
class A { public: void setA(int); void showA() const; private: int a; }; class B { public: void setB(int); void showB() const; private: int b; }; class C : public A, private B { public: void setC(int, int, int); void showC() const; private: int c; };
void A::setA(int x) { a=x; } void B::setB(int x) { b=x; } void C::setC(int x, int y, int z) { //派生类成员直接访问基类的 //公有成员 setA(x); setB(y); c = z; } //其他函数实现略 int main() { C obj; obj.setA(5); obj.showA(); obj.setC(6,7,9); obj.showC(); // obj.setB(6); 错误 // obj.showB(); 错误 return 0; }
#include <iostream> using namespace std; class Base1 { //基类Base1定义 public: void display() const { cout << "Base1::display()" << endl; } }; class Base2: public Base1 { //公有派生类Base2定义 public: void display() const { cout << "Base2::display()" << endl; } }; class Derived: public Base2 { //公有派生类Derived定义 public: void display() const { cout << "Derived::display()" << endl; } };
void fun(Base1 *ptr) { //参数为指向基类对象的指针 ptr->display(); //"对象指针->成员名" } int main() { //主函数 Base1 base1; //声明Base1类对象 Base2 base2; //声明Base2类对象 Derived derived; //声明Derived类对象 fun(&base1); //用Base1对象的指针调用fun函数 fun(&base2); //用Base2对象的指针调用fun函数 fun(&derived); //用Derived对象的指针调用fun函数 return 0; }
默认情况
C++11规定
派生类名::派生类名(基类所需的形参,本类成员所需的形参): 基类名(参数表), 本类成员初始化列表 { //其他初始化; };
#include<iostream> using namespace std; class B { public: B(); B(int i); ~B(); void print() const; private: int b; }; B::B() { b=0; cout << "B‘s default constructor called." << endl; } B::B(int i) { b=i; cout << "B‘s constructor called." << endl; } B::~B() { cout << "B‘s destructor called." << endl; } void B::print() const { cout << b << endl; } class C: public B { public: C(); C(int i, int j); ~C(); void print() const; private: int c; }; C::C() { c = 0; cout << "C‘s default constructor called." << endl; } C::C(int i,int j): B(i), c(j){ cout << "C‘s constructor called." << endl; } C::~C() { cout << "C‘s destructor called." << endl; } void C::print() const { B::print(); cout << c << endl; } int main() { C obj(5, 6); obj.print(); return 0; }
派生类名::派生类名(参数表) : 基类名1(基类1初始化参数表), 基类名2(基类2初始化参数表), ... 基类名n(基类n初始化参数表), 本类成员初始化列表 { //其他初始化; };
派生类名::派生类名(形参表): 基类名1(参数), 基类名2(参数), ..., 基类名n(参数), 本类成员(含对象成员)初始化列表 { //其他初始化 };
#include <iostream> using namespace std; class Base1 {//基类Base1,构造函数有参数 public: Base1(int i) { cout << "Constructing Base1 " << i << endl; } }; class Base2 {//基类Base2,构造函数有参数 public: Base2(int j) { cout << "Constructing Base2 " << j << endl; } }; class Base3 {//基类Base3,构造函数无参数 public: Base3() { cout << "Constructing Base3 *" << endl; } }; class Derived: public Base2, public Base1, public Base3 { public: Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b) //此处的次序与构造函数的执行次序无关 { } private: Base1 member1; Base2 member2; Base3 member3; }; int main() { Derived obj(1, 2, 3, 4); return 0; }
派生类未定义复制构造函数的情况
派生类定义了复制构造函数的情况
例 派生类对象析构举例
#include <iostream> using namespace std; class Base1 { public: Base1(int i) { cout << "Constructing Base1 " << i << endl; } ~Base1() { cout << "Destructing Base1" << endl; } }; class Base2 { public: Base2(int j) { cout << "Constructing Base2 " << j << endl; } ~Base2() { cout << "Destructing Base2" << endl; } }; class Base3 { public: Base3() { cout << "Constructing Base3 *" << endl; } ~Base3() { cout << "Destructing Base3" << endl; } }; class Derived: public Base2, public Base1, public Base3 { public: Derived(int a, int b, int c, int d): Base1(a), member2(d), member1(c), Base2(b) { } private: Base1 member1; Base2 member2; Base3 member3; }; int main() { Derived obj(1, 2, 3, 4); return 0; }
当派生类与基类中有相同成员时:
#include <iostream> using namespace std; class Base1 { public: int var; void fun() { cout << "Member of Base1" << endl; } }; class Base2 { public: int var; void fun() { cout << "Member of Base2" << endl; } }; class Derived: public Base1, public Base2 { public: int var; void fun() { cout << "Member of Derived" << endl; } }; int main() { Derived d; Derived *p = &d; //访问Derived类成员 d.var = 1; d.fun(); //访问Base1基类成员 d.Base1::var = 2; d.Base1::fun(); //访问Base2基类成员 p->Base2::var = 3; p->Base2::fun(); return 0; }
class A { public: void f(); }; class B { public: void f(); void g() }; class C: public A, piblic B { public: void g(); void h(); };
如果定义:C c1; 则 c1.f() 具有二义性 而 c1.g() 无二义性(同名隐藏) 例 多继承时的二义性和冗余问题
//7_7.cpp #include <iostream> using namespace std; class Base0 { //定义基类Base0 public: int var0; void fun0() { cout << "Member of Base0" << endl; } }; class Base1: public Base0 { //定义派生类Base1 public: //新增外部接口 int var1; }; class Base2: public Base0 { //定义派生类Base2 public: //新增外部接口 int var2; };
例 多继承时的二义性和冗余问题
class Derived: public Base1, public Base2 { public: int var; void fun() { cout << "Member of Derived" << endl; } }; int main() { //程序主函数 Derived d; d.Base1::var0 = 2; d.Base1::fun0(); d.Base2::var0 = 3; d.Base2::fun0(); return 0; }
#include <iostream> using namespace std; class Base0 { public: int var0; void fun0() { cout << "Member of Base0" << endl; } }; class Base1: virtual public Base0 { public: int var1; }; class Base2: virtual public Base0 { public: int var2; }; class Derived: public Base1, public Base2 { //定义派生类Derived public: int var; void fun() { cout << "Member of Derived" << endl; } }; int main() { Derived d; d.var0 = 2; //直接访问虚基类的数据成员 d.fun0(); //直接访问虚基类的函数成员 return 0; }
#include <iostream> using namespace std; class Base0 { public: Base0(int var) : var0(var) { } int var0; void fun0() { cout << "Member of Base0" << endl; } }; class Base1: virtual public Base0 { public: Base1(int var) : Base0(var) { } int var1; }; class Base2: virtual public Base0 { public: Base2(int var) : Base0(var) { } int var2; }; class Derived: public Base1, public Base2 { public: Derived(int var) : Base0(var), Base1(var), Base2(var) { } int var; void fun() { cout << "Member of Derived" << endl; } }; int main() { //程序主函数 Derived d(1); d.var0 = 2; //直接访问虚基类的数据成员 d.fun0(); //直接访问虚基类的函数成员 return 0; }
原文:https://www.cnblogs.com/aidata/p/13041506.html