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

时间:2021-06-11 11:38:32

标签: c++ templates

在这个例子中:

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

我无法调用派生的 createObj() 函数。似乎代码仍然试图使用 MyClass 实例调用基本版本,这会导致编译失败,因为没有传递所需的构造参数。为什么这不能作为正常的覆盖函数工作并调用提供正确参数的派生版本?

1 个答案:

答案 0 :(得分:1)

您误解了错误。 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> 尝试默认构造一个 MyClass,但 MyClass 没有默认构造函数。即使您不尝试调用 Base<MyClass>::createObj,该方法也必须有效,因为它是作为 Base<MyClass> 的一部分进行实例化的。

换句话说,仅仅实例化 Base<MyClass> 会失败。不调用该方法并不会减少错误。

我不完全确定目标是什么,但是如果您在 Base 您的代码 compiles without issues 中将该方法设为纯虚拟:

#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();
}

或者,您可以为 MyClass 提供默认构造函数。

相关问题