带有多态指针的类的复制构造函数的问题

时间:2010-12-22 08:57:30

标签: c++

我有两个领域的课,她们是抽象类的指针。如何编写复制构造函数将复制用两个指针指向的数据。

这是班级

class OSGFMenu;
class OSGFMenuItem;
typedef void(OSGFMenu::*OSGFMenuCommand)(OSGFMenuItem*);
typedef int (OSGFMenuItem::*FNMETHOD) ( int, char* );
class OSGFMenuItem:
    public OSGFDrawableComponent
{
public:
    OSGFMenuItem(Game& game,OSGFMenu& menu)
        :OSGFDrawableComponent(game),mMenu(menu),mActive(false)
    {
    }
    OSGFMenuItem(const OSGFMenuItem& menuItem)
        :OSGFDrawableComponent(menuItem),mMenu(menuItem.mMenu)
    {
        Copy(menuItem);
    }
    OSGFMenuItem& operator=(const OSGFMenuItem& menuItem)
    {
        if(&menuItem != this)
            Copy(menuItem);
        return *this;
    }
    void SetActive(bool active)
    {
        mActive = active;
    }
    void Activate()
    {
        SetActive(true);
    }
    void DeActivate()
    {
        SetActive(false);
    }
    void SetCommand(OSGFMenuCommand command)
    {
        mCommand = command;
    }
    virtual void Render()const
    {
        if(!mActive)
            DrawIfNotNull(mDrawData);
        else
            if(!DrawIfNotNull(mActiveDrawData))
                DrawIfNotNull(mDrawData);

    }
    virtual void Update(double dTime)
    {
        OSGFDrawableComponent* drawData = 
            dynamic_cast<OSGFDrawableComponent*>(mDrawData);
        if(drawData)
            drawData->Update(dTime);
    }
    void Invoke()
    {
        (mMenu.*mCommand)(this);
    }
    ~OSGFMenuItem()
    {
        SafeDelete(mDrawData);
        SafeDelete(mActiveDrawData);
    }
protected:
    void SetDrawData(IDrawable* drawData)
    {
        mDrawData = drawData;
    }
    void SetActiveDrawData(IDrawable* drawData)
    {
        mActiveDrawData = drawData;
    }
private:
    bool DrawIfNotNull(IDrawable* drawData)const
    {
        if(!drawData)return false;
        drawData->Render();
        return true;
    }
    void Copy(const OSGFMenuItem& menuItem)
    {
        mCommand = menuItem.mCommand;
        *mDrawData = *menuItem.mDrawData;
        *mActiveDrawData = *menuItem.mActiveDrawData;
        mActive = menuItem.mActive;
    }
    OSGFMenuCommand mCommand;
    OSGFMenu& mMenu;
    IDrawable* mDrawData;
    IDrawable* mActiveDrawData;
    bool mActive;
};

4 个答案:

答案 0 :(得分:3)

问题是是否必须复制多态指针所指向的对象。如果是这种情况,最好的选择是在包含的类层次结构中提供一个clone()虚拟方法,该方法将创建该对象的副本。

struct base {
   virtual base* clone() = 0;
   virtual void foo() = 0;
};
struct derived : base {
   virtual derived* clone() { return new derived(*this); }
   virtual foo();
};
class container {
   base * ptr;
public:
   container( base * p ) : ptr(p) {}
   container( container const & lhs ) : ptr( lhs.ptr->clone() ) 
   {}
};

答案 1 :(得分:2)

如果您需要复制 IDrawable 层次结构的确切类型,我认为您唯一的机会是向 IDrawable 接口添加Clone()抽象方法。

它的签名将是

IDrawable* clone() const;

如果需要修改const指向的对象,则可以省略this

答案 2 :(得分:2)

您需要一个虚拟副本构造函数来实现此目的。由于C ++不支持它,因此可以通过虚拟clone方法来模拟此效果。有关详细信息,请参阅What is a "virtual" constructor?

答案 3 :(得分:0)

您的IDrawable需要某种虚拟Clone()函数。