分配抽象类类型为"CObject"的对象 [英] Allocating an object of abstract class type 'CObject'

查看:115
本文介绍了分配抽象类类型为"CObject"的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用多态性和抽象类CObject来实现CWindow和其他元素.但是我收到一个错误消息分配抽象类类型为CObject的对象."

I want to implement CWindow and other elements using polymorphism and abstract class CObject. But I got an error 'Allocating an object of abstract class type 'CObject'.

    class CObject
{
public:
    CObject ( const int id, const string &title, const CRect &pos ):
    m_id(id),m_title(title),m_pos(make_unique<CRect>(pos))
    {
    }
    virtual void print ( ostream &os ) const = 0;
    virtual void add ( const CObject &src ){            
        m_src.push_back(make_unique<CObject>(src)); //->here the problem
    }
    friend ostream & operator << (ostream &os, const CObject &src ){
        src.print(os);
        return os;
    }
protected:
    int m_id;
    string m_title;
    unique_ptr<CRect> m_pos;
    vector< unique_ptr<CObject> > m_src;
};

例如,我要创建一个按钮,然后将该按钮添加到CWindow中(在主函数中).窗口具有绝对位置,但是窗口的其他部分取决于CWindow.然后,我想调整Window的大小,所有元素都会自动调整大小,因此我必须存储有关子元素的所有数据.

For example, I want to create a button, and then add the button to the CWindow (in the main function). The window has an absolute position, but other parts of the window depend on the CWindow. Then I want to resize the Window and all of the elements will resize automatically, so I have to store all data about sub-elements.

class CWindow : public CObject
    {
    public:
        CWindow ( const string & title, const CRect & absPos ): CObject(0,title,absPos)
        {
        };
        virtual void print ( ostream &os ) const{
            os << "CWindow";
        };
        CWindow & Add ( const CObject &src ){
            add(src);
            return *this;
        }
    };
class CButton : public CObject
{
public:
    CButton ( int  id, const CRect &relPos, const string &name ):
    CObject(id,name,relPos)
    {
    }
};

主要功能示例

    int main ( void )
    {
         CWindow a ( "Sample window", CRect ( 10, 10, 600, 480 ) );
            a . Add ( CButton ( 1, CRect ( 0.1, 0.8, 0.3, 0.1 ), "Ok" ) ) 
. Add ( CButton ( 2, CRect ( 0.6, 0.8, 0.3, 0.1 ), "Cancel" ) );
    }

推荐答案

CObject是抽象类,因为print()是抽象的.因此,您不能直接创建CObject的实例.您只能实例化实现print()的具体派生类.

CObject is an abstract class, because print() is abstract. As such, you CANNOT create instances of CObject directly. You can only instantiate concrete derived classes that implement print().

调用std::make_unique<CObject>(...)会尝试实例化CObject本身,这就是为什么它在您的代码中失败的原因.您需要改为指定派生类,例如:std::make_unique<CButton>(...).

Calling std::make_unique<CObject>(...) attempts to instantiate CObject itself, which is why it fails in your code. You need to specify a derived class instead, eg: std::make_unique<CButton>(...).

但是,由于多种原因,您显示的add()方法将不起作用:

However, the add() method you have shown will not work, for a number of reasons:

  • 它无法知道传递的CObject是分配在自动还是动态内存中.您显示的main()示例是在自动内存中创建对象,但是默认的std::unique_ptr(std::delete)删除程序需要动态内存.

  • there is no way for it to know whether the passed CObject was allocated in automatic or dynamic memory. The main() example you have shown is creating objects in automatic memory, but the default deleter of std::unique_ptr (std::delete) requires dynamic memory instead.

调用者无法指定正确的类型来传递给std::make_unique()T模板参数.

there is no way for the caller to specify the correct type to pass to the T template parameter of std::make_unique().

没有一个派生类具有将CObject作为输入的构造函数,因此您不能在std::make_unique()args参数中指定传递的CObject.

none of your derived classes have a constructor that takes a CObject as input, so you can't specify the passed CObject in the args parameter of std::make_unique().

您需要更改add()来代替std::unique_ptr<CObject>作为输入,然后可以将std::move()放入vector中,例如:

You need to change add() to take a std::unique_ptr<CObject> as input instead, and then you can just std::move() it into your vector, eg:

virtual void add(std::unique_ptr<CObject> src)
{
    m_src.push_back(std::move(src));
}

让调用者句柄构造所需的对象,add()只是拥有它的所有权:

Let the caller handle constructing the desired object, add() just takes ownership of it:

int main()
{
    CWindow a("Sample window", CRect(10, 10, 600, 480));
    a.add(std::make_unique<CButton>(1, CRect(0.1, 0.8, 0.3, 0.1), "Ok"));
    a.add(std::make_unique<CButton>(2, CRect(0.6, 0.8, 0.3, 0.1), "Cancel"));
}

否则,如果您希望add()代表呼叫方呼叫std::make_unique(),则您将需要更多类似以下内容:

Otherwise, if you want add() to call std::make_unique() on the caller's behalf, you would need something more like this instead:

template<class T, class... Args>
void add(Args&&... args)
{
    m_src.push_back(std::make_unique<T>(args));
}

...

int main()
{
    CWindow a("Sample window", CRect(10, 10, 600, 480));
    a.add<CButton>(1, CRect(0.1, 0.8, 0.3, 0.1), "Ok");
    a.add<CButton>(2, CRect(0.6, 0.8, 0.3, 0.1), "Cancel");
}

这篇关于分配抽象类类型为"CObject"的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆