Moi*_*oia 1 c++ templates clang c++11
我有这种结构:
静态库A
接口
class Interface
{
public:
virtual ~Interface() // no pure virtual dtor
virtual void pureMethod1() = 0;
virtual void pureMethod2() = 0;
virtual void virtualMethod1();
virtual void virtualMethod2();
};
Run Code Online (Sandbox Code Playgroud)
interface.cpp
include "interface.h"
Interface::~Interface() = default;
Interface::virtualMethod1() {}
Interface::virtualMethod2() {}
Run Code Online (Sandbox Code Playgroud)
使用A的静态库B
基准时间
#include "interface.h"
template<class T>
class BaseT final : public Interface
{
static_assert(false, "can't use this specialization");
};
Run Code Online (Sandbox Code Playgroud)
专门1.h
#include "baset.h"
using MyType = BaseT<CustomClass1>;
template<>
class BaseT<CustomClass1> : public Interface
{
public:
BaseT() = default;
void pureMethod1() final {}
void pureMethod2() final {}
};
Run Code Online (Sandbox Code Playgroud)
专门2.h
#include "baset.h"
using MyType = BaseT<CustomClass2>;
template<>
class BaseT<CustomClass2> : public Interface
{
public:
BaseT() = default;
void pureMethod1() final {}
void pureMethod2() final {}
};
Run Code Online (Sandbox Code Playgroud)
我在两个完全专业的课程中都收到了来自clang的警告:
警告:“ BaseT没有离线虚拟方法定义:其vtable将在每个翻译单元中发出”
为什么会有这个警告?我没有任何纯虚拟析构函数,并且在基类中提供了默认的析构函数。以及由于使用模板,如何避免使用离线虚拟方法?
虚拟函数的重排通常通过使用函数指针表vtable来实现。每个实现该接口(即从该接口继承)的类都具有一个表,其中的条目指向其对虚拟功能的实现。该表必须位于编译期间生成的至少一个目标文件中,并且默认情况下,许多编译器将其放在包含该类中第一个虚函数的实现的目标文件中。
在您的情况下,所有专业化的虚函数BaseT都在类声明中内联定义。在这种情况下,没有可放入其实现的唯一目标文件,它们将包含在使用它的所有目标文件中。这反过来意味着将vtable与第一个虚拟函数的实现放在一起的方法将不再起作用。这使编译器后退以向所有目标文件添加vtable版本,以确保安全,并使程序员意识到这一点,从而发出警告。
这并不是真正的问题,因为链接器将从目标文件之一中选择vtable并将其包含在最终二进制文件中。
| 归档时间: |
|
| 查看次数: |
2326 次 |
| 最近记录: |