为以下代码创建了多少个虚拟表? 我正在学习C++,并对虚拟表有一个问题,帮助我理解这个问题。 我想知道这个程序中创建了多少个表 #include <iostream> class A { public: virtual void f() { } }; class B : public A { }; class C : public B { }; #包括 A类{public:virtualvoid f(){}; B类:公共A{}; C类:公共B{};

为以下代码创建了多少个虚拟表? 我正在学习C++,并对虚拟表有一个问题,帮助我理解这个问题。 我想知道这个程序中创建了多少个表 #include <iostream> class A { public: virtual void f() { } }; class B : public A { }; class C : public B { }; #包括 A类{public:virtualvoid f(){}; B类:公共A{}; C类:公共B{};,c++,vtable,C++,Vtable,答案是3个虚拟表。您在这里创建了3个类,这意味着这段代码将有3个虚拟表 为以下代码创建了多少个虚拟表 < C++语言没有定义虚拟表之类的东西。这是一种实现虚拟调度的方法。由于这是一个实现细节,虚拟表的数量也不是由语言定义的,而是由语言实现决定的 因此,除非问题仅限于某些特定的语言实现,否则没有答案。使用示例语言实现,为以下每个类创建了一个虚拟表: std::exception std::bad_exception std::type_info std::bad_cast std::bad_typ

答案是3个虚拟表。您在这里创建了3个类,这意味着这段代码将有3个虚拟表

为以下代码创建了多少个虚拟表

< C++语言没有定义虚拟表之类的东西。这是一种实现虚拟调度的方法。由于这是一个实现细节,虚拟表的数量也不是由语言定义的,而是由语言实现决定的

因此,除非问题仅限于某些特定的语言实现,否则没有答案。使用示例语言实现,为以下每个类创建了一个虚拟表:

std::exception
std::bad_exception
std::type_info
std::bad_cast
std::bad_typeid
std::bad_alloc
std::bad_array_new_length
std::nested_exception
__cxxabiv1::__forced_unwind
std::locale::facet
std::__cxx11::collate<char>
std::__cxx11::collate<wchar_t>
std::__cxx11::collate_byname<char>
std::__cxx11::collate_byname<wchar_t>
std::logic_error
std::domain_error
std::invalid_argument
std::length_error
std::out_of_range
std::runtime_error
std::range_error
std::overflow_error
std::underflow_error
std::_V2::error_category
std::system_error
std::ios_base::failure
std::ios_base
std::basic_streambuf<char>
std::basic_streambuf<wchar_t>
std::ctype<char>
std::__ctype_abstract_base<wchar_t>
std::ctype<wchar_t>
std::ctype_byname<char>
std::ctype_byname<wchar_t>
std::__cxx11::numpunct<char>
std::__cxx11::numpunct<wchar_t>
std::__cxx11::numpunct_byname<char>
std::num_get<char>
std::num_put<char>
std::__cxx11::numpunct_byname<wchar_t>
std::num_get<wchar_t>
std::num_put<wchar_t>
std::basic_ios<char>
std::basic_ios<wchar_t>
std::basic_ostream<char>
std::basic_ostream<wchar_t>
std::basic_istream<char>
std::basic_istream<wchar_t>
std::basic_iostream<char>
std::basic_iostream<wchar_t>
A
B
C

假设创建了任何vtable(这是编译器的一个实现细节,不是由标准规定的),那么可能会有3个vtable,每个类一个,但这3个vtable将指向
f()
的同一个副本,因为此代码中没有涉及重写副本。编译器可以做任何它想做的事情。如果编译器有更好的方法,可以是零v表。它是实现定义的。没有人与您的示例中的最相似,因为您没有重写虚拟方法。为什么不能只有一个虚拟表?@user975989,因为有3个不同的类。用户代码可以随时创建其中任何一个。编译器需要能够取消引用指向其中任何一个的指针,才能访问有效的vtable。所以需要有3个独立的vtable。@RemyLebeau-并且这些对象中的任何一个都可以指向一个vtable。将调用相同的精确函数。“但是RTTI呢”,你可能会说。嗯,代码示例中没有使用它。编译器可以证明单个vtable可能不需要RTTI信息,因此可以重用(编译器标志也可能有助于重用)。这就是为什么这些问题(以及回答这些问题的尝试)在以最一般的方式提问时是没有意义的。
g++ -fdump-lang-class -std=c++17 main.cpp \
    && grep Vtable main.cpp.*.class \
     | cut -f 3 -d ' '