首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

虚基类,该如何处理

2012-03-05 
虚基类//如果一个派生类中有一个直接或间接的虚基类,那么派生类的构造函数//的成员初始化列表必须列出对虚

虚基类
//如果一个派生类中有一个直接或间接的虚基类,那么派生类的构造函数
//的成员初始化列表必须列出对虚基类构造函数的调用。如果没有列出,
//则使用该虚基类的默认构造函数来初始化派生类对象的虚基类对象。

//这个是我总结的两句话:(假如各个派生类都有参数)
//A:就是如果一个派生类存在间接虚基类的话,虚基类中的构造函数应该是
//在派生类中显示列出来,而被调用。

//B:但是如果派生类中没有虚基类的话,应该是这个基类的直接派生类调用这个
//基类的构造函数,而不是这个基类的间接派生类去调用基类的构造函数。


//对于第二句话(其实这里写个类a继承类b,类b继承类c理解起来可能更好。
//看这个程序://基类child并没有调用base基类中的函数(呵呵调用了构造函数哦)
                                        //所以没有二异性只不过child1和child2应该还是都拷贝了类base的成员
                            //如果对于上面这个不清楚去看看二异性是什么?
#include <iostream>
using   namespace   std;
class   base  
{
public:
            base(int   i):a(i)
            {
                        cout < < "base= " < <i < <endl;

            }
            void   print()
            {
            }
private:
            int   a;
};

class   child1   :   public   base  
{
public:
            child1(int   i):base(i)
            {
                        cout < < "child1= " < <i < <endl;

            }
private:
            int   b;
};

class   child2:     public   base
{
public:
            child2(int   i):base(i)
            {
                        cout < < "child2= " < <i < <endl;

            }
private:
            int   c;
};

class   child:public   child1,public   child2
{
public:
            child(int   a,int   b):child1(a),child2(b)//,base(a)
            {
                        cout < < "child= " < <a < <endl;
                        cout < < "child= " < <b < <endl;

            }
private:
};

int   main()
{
            //child2   obj(2);
            child   obj(1,2);
           
            return   0;
}


//对于A:看这个
#include <iostream>
using   namespace   std;

class   base  
{
public:
            base(int   i):a(i)
            {
                        cout < < "base= " < <i < <endl;



            }
            void   print()
            {
            }
private:
            int   a;
};

class   child1   :   virtual   public   base  
{
public:
            child1(int   i):base(i)
            {
                        cout < < "child1= " < <i < <endl;

            }
private:
            int   b;
};

class   child2:   virtual   public   base
{
public:
            child2(int   i):base(i)
            {
                        cout < < "child2= " < <i < <endl;

            }
private:
            int   c;
};

class   child:public   child1,public   child2
{
public:
            child(int   a,int   b):child1(a),child2(b),base(a)
            {
                        cout < < "child= " < <a < <endl;
                        cout < < "child= " < <b < <endl;

            }
private:
};

int   main()
{
            //child2   obj(2);
            child   obj(1,2);
            return   0;
}


//只不过这里有人就纳闷了,child是继承了来自child1和chind2的数据成员,
//但是由于base是虚基类,所以应该只拷贝一份副本给child1或child2。
//那这份副本是拷贝给了哪个类?是child1?还是child2?
//呵呵接着看吧。。
//假如我们建立了一个child的对象obj他应该先调用它的直接基类,(按照
//那个写的顺序调用)
//但是这个直接基类还有个基类(就是base),所以又会去调用它的祖先,
//就是说这个child1或者是child2调用了这个base吗   ?
//   如果这样想就大错特错了。
              //其实我们之前也强调如果一个派生类中有一个直接或
              //间接的虚基类,那么派生类的构造函数的成员初始化列表必须列出对虚基
              //类构造函数的调用。
              //为什么这样呢?其实C++规定是你建立对象的那个类中的构造函数去调用虚基类,
              //,不是那个虚基类的直接派生类去调用。
              //编译器会忽略虚基类的直接派生类去调用,这样就可以防止对虚基类的对象只初始化一次。但是它还是会去调用直接基类的构造函数,毕竟派生类会继承基类的很多东西。


[解决办法]
我没有看程序,只看了你写的文字(还没有全看),我本人是学C++不到一个月
但是我有点个人想法,

你可能想错了,

-〉//那这份副本是拷贝给了哪个类?是child1?还是child2?
----------------------
并没有给child1,childe2 两个中的任何一个,而是给了childe;

个人之言
[解决办法]
-〉并没有给child1,childe2 两个中的任何一个,而是给了childe;

打错了是:并没有给child1,child2 两个中的任何一个,而是给了child;

------解决方案--------------------


mark..
[解决办法]
比较混乱,楼主到底想要问什么?

热点排行