在不同项目(没有编译时链接)使用的标头中声明的纯抽象C++类是否共享相同的虚拟表模型
Does a pure abstract C++ class declared in a header used in different projects (without compile time linking) share the same Virtual Table model?
我有一个C++头,声明了一个仅由纯虚拟方法组成的类。我有两个使用该标头的 DLL(其中一个实现该接口(,但在编译时未链接。一个 DLL 动态加载另一个 DLL,将实现的接口的指针传递给另一个。这些 DLL 是否共享相同的虚拟表结构?
当然,类头足以构建完整的类(这里讲的是内存中的布局,所有内容是如何定位的,而不是其中的实际数据(,包括精确的虚拟表结构。
想想看,每个链接对象(您的.cpp文件(都是单独编译的,只有头文件是通用的,但在编译时,编译器必须知道虚拟表的精确结构才能正确路由虚拟调用。
顺便通读一个问题...
如果我理解正确,你会得到这样的东西:
啊
class A
{
public:
virtual void foo()=0;
}
B.cpp
#include <A.h>
class B : public A
{
public:
void foo()
{}
}
C.cpp
#include <A.h>
void bar(A * a)
{}
所以B.cpp
有一个实现A
的类,C.cpp
有一些函数接受指向A
实例的指针(你提供了B
的实例(。 这是对的吗?
如果是这样,那么是的,这些共享一个 vtable。 vtable是通过编译类B
创建的,C.cpp
根本没有自己的vtable。
你很安全。
方法在vftable
中出现的顺序由基类结构决定,这就是您应该关心的全部内容。但这是特定于编译器的,因此使用相同的编译器来生成 dll。不要依赖它们向后兼容(或至少检查文档(。
假设您有以下标头:
//header.h
class A
{
public:
virtual void foo() = 0;
virtual void goo() = 0;
};
并且您B.dll
以下类:
class B : public A
{
public:
virtual void foo() {}
virtual void goo() {}
}
现在,在 X.dll
中,您会收到一个指向A
的指针,该指针是在 B.dll
中创建的B
对象。
电话会议
void test( A* a )
{
a->foo();
}
将调用B::foo()
.
你可以尝试的一个简洁的实验是用header.h
编译B.dll
,当你编译X.dll
时,反转方法的顺序header.h
:
//header.h
class A
{
public:
virtual void goo() = 0;
virtual void foo() = 0;
};
在这种情况下,尽管您永远不应该这样做,但在 X.dll
中对 test()
的相同调用可能会调用该方法B::goo()
。这是因为X.dll
假定标头中存在vftable
。不过,这是未定义的行为;我写这个例子只是为了说明一个观点。
这完全取决于编译器,但通常,当一个类是纯虚拟的并且没有在翻译单元中定义任何成员函数时,编译器将生成vtable
作为弱符号。在您的特定情况下,不同的翻译单元将为基类型生成单独的完全相等的vtable
,链接器/加载器将丢弃除一个符号之外的所有符号,就像丢弃任何其他弱符号一样(想想模板化的非内联函数(。
但请注意,vtable
的生成不是标准化的,这意味着如果您混合来自两个不同编译器甚至版本的代码,可能会导致 ODR 冲突。
- 无法创建抽象类的实例
- 如何定义一个纯抽象基类
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 用pybind11包装C++抽象类时出错
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 抽象类错误,请参阅声明" "是抽象的
- 将自定义函数传递到基抽象类中以延迟执行
- 命名参数习惯用法和(抽象)基类
- 打印抽象对象 c++
- 如何在从抽象基派生的类中实现相同的方法?
- 将包含抽象类和普通类C++包导出到 Python
- C++:处理抽象类中的错误时出现问题
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- C++抽象的字节序是中立的吗?
- 在 C++ 中使用另一个头文件中的抽象类
- ATL::CComContainedObject<contained>: C2259 无法实例化抽象类
- C++:从抽象类重写纯虚拟运算符重载
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 位集元素迭代的抽象