且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

分配抽象类类型为"CObject"的对象

更新时间:2023-02-09 14:27:16

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");
}