CBase中定义:typedef vector<CBase*> CBases;
typedef CBases::iterator CBITERATOR;CBases m_children;virtual void Read();构造函数中:CBase::CBase()
{
    CBase *p;
    m_children.push_back(p); //应当怎样直接存放子类指针?
}Read函数实现多态:void CBase::Read()
{
    CBITERATOR ite;    for (ite = m_children.begin(); ite != m_children.end(); ite++)
    {
        (*ite)->Read(); //这里应该每次取出一个子类指针来调用各自的Read()函数
    }
}派生子类CDerive1,CDerive2:void CDerive1::Read()
{
    AfxMessageBox(_T("CDerive1"));
}
void CDerive2::Read()
{
    AfxMessageBox(_T("CDerive2"));
}
我在基类Read函数中可以使用实时赋值的方式实现多态,    *ite = CDerive1;
   (*ite)->Read();这样就又得枚举,然后switch,不方便新加子类,有什么办法让容器中直接放子类指针?或者如何解决?

解决方案 »

  1.   

    CBase::CBase()
    {
        m_children.push_back(this); 
    }CDerive1::CDerive1()
    {
        m_children.push_back(this); 
    }CDerive2::CDerive2()
    {
        m_children.push_back(this); 
    }
      

  2.   

    CBase::CBase(CBase* p)
    {
        m_children.push_back(p); //应当怎样直接存放子类指针?
    }CDerive1::CDerive1():CBase(this)
    {}CDerive1::CDerive2():CBase(this)
    {}
      

  3.   

    第一种方法中,m_children必须是protected属性或者public
    CBase::CBase()
    {
        m_children.push_back(this); 
    }CDerive1::CDerive1()
    {
        m_children.push_back(this); 
    }CDerive2::CDerive2()
    {
        m_children.push_back(this); 
    }
    第二种方法
    CBase::CBase(CBase* p) 

        m_children.push_back(p); 
    } CDerive1::CDerive1():CBase(this) 
    { } CDerive1::CDerive2():CBase(this) 
    { }
    个人感觉第2种更好。谢谢!
      

  4.   


    CBase::CBase()
    {
        m_children.push_back(this); 
        AfxMessageBox(_T("CBase"));
    }CDerive1::CDerive1()
    {
        m_children.push_back(this); 
        AfxMessageBox(_T("CDerive1")); //没执行到
    }CDerive2::CDerive2()
    {
        m_children.push_back(this); 
        AfxMessageBox(_T("CDerive2")); //没执行到
    }在另一个类中调用时:CBase *m_pBase;
    m_pBase = new CBase;
    m_pBase->Read()基类可以构造,子类好像没执行构造,怎么回事?
    第二种方法在各自头文件里要将构造函数写成什么形式?暂时编译不过。
      

  5.   

    应该这样写:CBase::CBase(CBase* p)  
    {  
        m_children.push_back(p);  
    }  CDerive1::CDerive1() : CBase(this)
    {  }  CDerive1::CDerive2() : CBase(this)
    {  } 这样存放到m_children中的就是实际指向各具体派生类对象的指针。
    调用时这样写:CBase *m_pBase;m_pBase = new CDerive1();
    m_pBase->Read();      // 调用CDerive1中实现的Readm_pBase = new CDerive2();
    m_pBase->Read();      // 调用CDerive2中实现的Read
      

  6.   

    5楼的做法我用过,运行正常,但是这样我每次调用子类方法前都得判断一下需要调用哪个子类,switch...case一下
    这样不大方便子类的添加
    前面几楼的方法似乎子类构造函数没被执行到,怎么回事?
      

  7.   

    不是很明白你的意思,调用子类的什么方法?Read()?如果是调用虚方法,直接这样用就可以了。
      

  8.   

    这样用是可以,我的意思是能不能不用
    m_pBase = new CDerive1();
    m_pBase = new CDerive2();
    这样的实时赋值,直接拿出m_chirlren中存放的指针就可以用
    目前m_chirlren中存放的仍然是基类指针,我试了很久都无法把子类指针直接存进去
      

  9.   

    你用m_pBase = new CBase();当然就是存放指向基类对象的指针,不用
    m_pBase = new CDerive1(); 
    m_pBase = new CDerive2(); 程序怎么知道你要实例化哪个具体的类呢?
    建议设计上做些调整可能会规避你遇到的这个问题。
      

  10.   

    我使用的是虚函数,那么:
    void CBase::Read()
    {
        ...
        (*ite) = CDerive1; //这句必须有?
        (*ite)->Read(); //上面那句没有的话,似乎仍然执行基类Read(),成了无限递归了...
    }
      

  11.   

    设计上如何调整?
    我想在框架类里调用CBase里的方法,用过虚函数多态性实现多次调用CBase::Read()时分别调用不同子类CDerive里的Read()
      

  12.   

    基类CBase中的Read()函数实现通用的业务逻辑,而在各派生类中针对具体情况分别实现,并根据设计的情况看是否调用CBase::Read()。如果没有通用的业务逻辑,那么在基类中的Read()中可以不实现。而楼主的代码:中,在CBase的Read()中不应该调用Read()。
      

  13.   


    /***this is Base.h ***/#pragma once
    #include<vector>
    #include <iostream>
    using namespace std;
    class CBase;
    typedef std::vector<CBase*> CBases;
    typedef CBases::iterator CBITERATOR;class CBase
    {
    //typedef std::vector<CBase*> CBases;
    //typedef CBases::iterator CBITERATOR; static CBases* m_pChildren;public:
    CBase(void);
    ~CBase(void); CBase(CBase* p) 

    if(NULL==m_pChildren)
    {
    m_pChildren=new CBases;
    }
    m_pChildren->push_back(p); 
    }   virtual  void Read()
    {
    CBITERATOR ite; for (ite = m_pChildren->begin(); ite != m_pChildren->end(); ite++)
    {
    (*ite)->Read(); //这里应该每次取出一个子类指针来调用各自的Read()函数
    }
    }

    };//CBases* CBase::m_pChildren=NULL;class CDerive1: public CBase
    {
    public:
    CDerive1():CBase(this)
    { } 
    void Read() 

    //AfxMessageBox(_T("CDerive1")); 
    cout<< "CDerive1";

    };class CDerive2: public CBase
    {
    public:
    CDerive2():CBase(this)
    { } 
    void Read() 

    //AfxMessageBox(_T("CDerive2")); 
    cout<< "CDerive2";

    };
      

  14.   

    // TestBase.cpp : 定义控制台应用程序的入口点。
    //#include "stdafx.h"#include "Base.h"
    int _tmain(int argc, _TCHAR* argv[])
    { CBase base;
    CDerive1 c1;
    CDerive2 c2; c1.Read();
    int i=0;
    cin>>i; CBase* p=&c1;
    p->Read(); cin>>i;
    base.Read();
    cin>>i;
    return 0;
    }
      

  15.   


    /**  **/
    #include "StdAfx.h"
    #include "Base.h"CBases* CBase::m_pChildren=NULL;//// <-----------
    CBase::CBase(void)
    {
    }CBase::~CBase(void)
    {
    }
      

  16.   


    /***this is Base.h ***/#pragma once
    #include<vector>
    #include <iostream>
    using namespace std;
    class CBase;
    typedef std::vector<CBase*> CBases;
    typedef CBases::iterator CBITERATOR;class CBase
    {
    //typedef std::vector<CBase*> CBases;
    //typedef CBases::iterator CBITERATOR; static CBases* m_pChildren;

    static CBase* _pBase;
    public:
    CBase(void);
    ~CBase(void); CBase(CBase* p) 

    if(NULL==_pBase)
    {
    _pBase=new CBase;
    } if(NULL==m_pChildren)
    {
    m_pChildren=new CBases;
    }
    m_pChildren->push_back(p); 
    }   virtual  void Read()
    {
    CBITERATOR ite; for (ite = m_pChildren->begin(); ite != m_pChildren->end(); ite++)
    {
    (*ite)->Read(); //这里应该每次取出一个子类指针来调用各自的Read()函数
    }
    }

    CBase* getBase()
    {
    return _pBase;
    }
    };//CBases* CBase::m_pChildren=NULL;class CDerive1: public CBase
    {
    public:
    CDerive1():CBase(this)
    { } 
    void Read() 

    //AfxMessageBox(_T("CDerive1")); 
    cout<< "CDerive1";

    };class CDerive2: public CBase
    {
    public:
    CDerive2():CBase(this)
    { } 
    void Read() 

    //AfxMessageBox(_T("CDerive2")); 
    cout<< "CDerive2";

    };/**  **/
    #include "StdAfx.h"
    #include "Base.h"CBases* CBase::m_pChildren=NULL;CBase* CBase::_pBase=NULL;
    CBase::CBase(void)
    {
    }CBase::~CBase(void)
    {
    }// TestBase.cpp : 定义控制台应用程序的入口点。
    //#include "stdafx.h"#include "Base.h"
    int _tmain(int argc, _TCHAR* argv[])
    { CBase base;
    CDerive1 c1;
    CDerive2 c2; c1.Read();
    int i=0;
    cin>>i; CBase* p=&c1;
    p->Read(); cin>>i;
    base.Read();
    cin>>i; CBase* pBase=c1.getBase();
    pBase->Read();
    return 0;
    }