简体   繁体   English

C++ - 覆盖虚拟模板化成员函数

[英]C++ - Overriding Virtual Templated Member Functions

In this example:在这个例子中:

class MyClass
{
public:
    MyClass(int i);
};

template<typename T>
class Base
{
public:
    virtual std::unique_ptr<T> createObj()
    {
        return std::make_unique<T>();
    }
};

class Derived  : public Base<MyClass>
{
public:
    std::unique_ptr<MyClass> createObj() override
    {
        return std::make_unique<MyClass>(4);
    }
};

int main() 
{
    Derived instance;
    auto createdObj = instance.createObj();
}

I cannot call the derived createObj() function.我不能调用派生的 createObj() function。 It seems the code is trying to still call the base version with the MyClass instance which leads to compilation failures since the required construction arguments are not passed.似乎代码仍在尝试使用 MyClass 实例调用基本版本,这会导致编译失败,因为所需的构造 arguments 未通过。 Why does this not work as a normal overriden function and call the derived version that does supply the correct arguments?为什么这不能作为正常的覆盖 function 并调用提供正确 arguments 的派生版本?

You misinterpreted the error.您误解了错误。 The error message is :错误信息是

In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-10.3.0/lib/gcc/x86_64-linux-gnu/10.3.0/../../../../include/c++/10.3.0/memory:83:
/opt/compiler-explorer/gcc-10.3.0/lib/gcc/x86_64-linux-gnu/10.3.0/../../../../include/c++/10.3.0/bits/unique_ptr.h:962:34: error: no matching constructor for initialization of 'MyClass'
    { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
                                 ^
<source>:15:21: note: in instantiation of function template specialization 'std::make_unique<MyClass>' requested here
        return std::make_unique<T>();
                    ^
<source>:19:7: note: in instantiation of member function 'Base<MyClass>::createObj' requested here
class Derived  : public Base<MyClass>
      ^
<source>:6:5: note: candidate constructor not viable: requires single argument 'i', but no arguments were provided
    MyClass(int i);
    ^
<source>:3:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class MyClass
      ^
<source>:3:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
1 error generated.

Base<MyClass> tries to default construct a MyClass but MyClass has no default constuctor. Base<MyClass>尝试默认构造MyClassMyClass没有默认构造函数。 Even if you are not trying to call Base<MyClass>::createObj the method must be valid because it is instantiated as part of Base<MyClass> .即使您不尝试调用Base<MyClass>::createObj该方法也必须有效,因为它是作为Base<MyClass>的一部分实例化的。

In other words, merely instantiating Base<MyClass> will fail.换句话说,仅仅实例化Base<MyClass>将会失败。 Not calling the method does not make it less of an error.不调用该方法并不能减少错误。

I am not entirely sure whats the aim, but if you make the method pure virtual in Base your code compiles without issues :我不完全确定目标是什么,但是如果您在Base中将该方法设为纯虚拟,则您的代码编译不会出现问题

#include <memory>

class MyClass
{
public:
    MyClass(int i) {}
};

template<typename T>
class Base
{
public:
    virtual std::unique_ptr<T> createObj() = 0;
};

class Derived  : public Base<MyClass>
{
public:
    std::unique_ptr<MyClass> createObj() override
    {
        return std::make_unique<MyClass>(4);
    }
};

int main() 
{
    Derived instance;
    auto createdObj = instance.createObj();
}

Alternatively you could provide a default contructor for MyClass .或者,您可以为MyClass提供默认构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM