简体   繁体   English

C ++继承,模板和覆盖

[英]C++ inheritance, templates, and override

I'm having some trouble formalizing an interface to a template class. 我在规范与模板类的接口时遇到了一些麻烦。 Why does the following compile? 为什么会编译以下内容?

class IFoo {
public:
    virtual void functionA()=0;
};

template<class T>
class Foo : public IFoo{
public:
    void functionA() override { };
    void functionB() override { };
};

functionB obviously does not exist in IFoo, so why is the compiler not throwing an error? functionB在IFoo中显然不存在,那么为什么编译器不抛出错误? Currently running on GCC 5.4. 目前正在GCC 5.4上运行。

A bit of background as to how I came to this issue: I'm putting together some code for a side project of mine which depends heavily on common linear algebra routines. 关于我如何处理此问题的一些背景知识:我正在为我的一个副项目编写一些代码,该代码在很大程度上取决于常见的线性代数例程。 I want to abstract over the choice of library in order to eg facilitate benchmarking. 我想对库的选择进行抽象,以例如促进基准测试。 The idea is to use an interface like IFoo to do this, so that the business logic code only knows about IFoo rather than have to accomodate the quirks of any single linear algebra lib. 想法是使用类似IFoo的接口来执行此操作,以便业务逻辑代码仅了解IFoo,而不必适应任何单个线性代数库的怪癖。 This is feasible because there are only a handful of key functions that are necessary; 这是可行的,因为仅需要几个关键功能。 I'm not looking to provide an interface for all available operations. 我不想为所有可用的操作提供接口。 I need the templates to allow for processing using different degrees of precision, eg float, double, minifloats, etc. to be handled by the same subclass. 我需要模板,以允许使用不同精度的处理,例如,浮点数,双精度数,小浮点数等由同一子类处理。

In my head a sensible design for this problem is re-wrapping access to these libs with this interface in separate compilation units to produce independent static or runtime libraries that implement this interface. 在我看来,针对此问题的明智设计是使用此接口在单独的编译单元中重新包装对这些库的访问,以生成实现此接口的独立静态库或运行时库。 Switcing from one lib to another would then be as simple as linking against the desired library; 从一个库到另一个库的交换就像链接到所需库一样简单。 no changes in code are necessary. 无需更改代码。 Any thoughts on this general strategy also appreciated! 任何对此总体策略的想法也表示赞赏!

Templates are instantiated only if some other code uses them. 仅当其他一些代码使用模板时,才会实例化模板。 Your example doesn't have that code so it really doesn't matter whether this compiles or not. 您的示例没有该代码,因此无论是否编译都没有关系。 Try creating an object of Foo<int> and see for yourself that GCC will then complain. 尝试创建Foo<int>的对象,然后亲自查看GCC会抱怨。

You only defined a class template but you did not instantiate it. 您仅定义了一个类模板,但没有实例化它。 Excerpt from the template reference : 模板参考摘录:

A class template by itself is not a type, or an object, or any other entity. 类模板本身不是类型,对象或任何其他实体。 No code is generated from a source file that contains only template definitions. 从仅包含模板定义的源文件中不会生成任何代码。 In order for any code to appear, a template must be instantiated: 为了显示任何代码,必须实例化模板:

If you tried to instantiate an object with: 如果尝试使用以下方法实例化对象:

int main() {
    std::unique_ptr<IFoo> p = std::make_unique<Foo<void>>();
}

then GCC would complain with: 那么GCC会抱怨:

error: 'void Foo::functionB() [with T = void]' marked 'override', but does not override 错误:“ void Foo :: functionB()[with T = void]”标记为“ override”,但未覆盖
void functionB() override { }; void functionB()覆盖{};

Live example on Coliru 关于Coliru的实时示例
While the above compiles on VS if you tried to call a member function with: 虽然以上尝试在VS上编译,但您尝试使用以下方法调用成员函数:

p->functionB();

you would receive the following errors: 您将收到以下错误:

'functionB' : is not a member of 'IFoo' 'functionB':不是'IFoo'的成员
class "IFoo" has no member "functionB" 类“ IFoo”没有成员“ functionB”

That being said it is unclear where in your class you are actually using the template. 话虽如此,目前尚不清楚您实际上在模板中的哪个位置使用模板。 If you removed the template<class T> you would get the errors you expected in the first place. 如果删除了template<class T>您将首先得到您期望的错误。

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

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