zoukankan      html  css  js  c++  java
  • 虚基类

    解决多重继承中,一个公共基类可能在派生类中产生多个拷贝的现象。

    如:有一个公共基类A,类B和类C都有类A派生,类D由类B和类C派生,则类D含有类A的两个拷贝,这不仅多占内存,还可能造成多个拷贝中的数据不一致。

    #include <iostream>
    using namespace std;
    class A {
    public:
    	int x;
    	A(int a = 0) { x = a; }
    };
    
    class B:public A {
    public:
    	int y;
    	B(int a = 0, int b = 0):A(b) { y = a; }
    	void PB() { cout << "x=" << x << "y=" << y << '\n'; }
    };
    
    class C:public A {
    public:
    	int z;
    	C(int a = 0, int b = 0):A(b) { z = a; }
    	void PC() { cout << "x=" << x << "z=" << z << '\n'; }
    };
    
    class D:public B, public C {
    public:
    	int m;
    	D(int a, int b, int d, int e, int f):B(a, b), C(d, e) { m = f; }
    	void Print() {
    		PB();
    		PC();
    		cout << "m=" << m << '\n';
    	}
    };
    
    int main(void)
    {
    	D d(100, 200, 300, 400, 500);
    	d.Print();
    	return 0;
    }
    
    
    输出:

    x=200y=100
    x=400z=300
    m=500

     

    D中包含类A的两个拷贝,从两个不同的x可以看出来。

     

     

     

    在多重接继承中,如果希望公共基类在派生类中只有一个拷贝,可在定义派生类时将公共基类的类名前加上virtual即可。

    #include <iostream>
    using namespace std;
    class A {
    public:
    	int x;
    	A(int a = 0) { x = a; }
    };
    
    class B:virtual public A { //加virtual
    public:
    	int y;
    	B(int a = 0, int b = 0):A(b) { y = a; }
    	void PB() { cout << "x=" << x << "y=" << y << '\n'; }
    };
    
    class C:virtual public A { //加virtual
    public:
    	int z;
    	C(int a = 0, int b = 0):A(b) { z = a; }
    	void PC() { cout << "x=" << x << "z=" << z << '\n'; }
    };
    
    class D:public B, public C {
    public:
    	int m;
    	D(int a, int b, int d, int e, int f):B(a, b), C(d, e) { m = f; }
    	void Print() {
    		PB();
    		PC();
    		cout << "m=" << m << '\n';
    	}
    };
    
    int main(void)
    {
    	D d(100, 200, 300, 400, 500);
    	d.Print();
    	return 0;
    }
    
    
    输出:

    x=0y=100
    x=0z=300
    m=500

     

    解释:先调用虚基类的构造函数,然后调用非虚基类的构造函数。

     

    类D的构造函数分别调用类B和类C的构造函数,由于类A在类D中只有一个拷贝,编译器无法确定是由类B还是类C的构造函数来调用类A的构造函数,这种情况下,编译器约定执行类B和类C的构造函数时都不调用虚基类A的构造函数,二是子类D的构造函数中直接调用虚基类A的默认构造函数,因此x为0.

  • 相关阅读:
    7人脸识别
    1图片视频文件操作基础
    3直方图与二值化,图像梯度
    6模板匹配(人脸匹配案例)
    基础习题
    碎片知识点整理
    详解:MySQL数据表损坏的正确修复方案
    前端开发:模块化 — 高效重构
    分享几个基于jQuery不错的前端相册展示插件代码
    程序员编程10年的心得和体会
  • 原文地址:https://www.cnblogs.com/helloweworld/p/2840992.html
Copyright © 2011-2022 走看看