开发者

Does the C++ spec allow an instance of a non-virtual class to include memory for a vtable pointer?

开发者 https://www.devze.com 2023-03-01 02:42 出处:网络
Does the C++ spec allow an instance of a non-virtual class to include memory for a vtable pointer? I am asking this, because a colleague said he once used a C++ compiler where the following happened:

Does the C++ spec allow an instance of a non-virtual class to include memory for a vtable pointer? I am asking this, because a colleague said he once used a C++ compiler where the following happened:

  class MyClass
  {

     public:

     HeaderStruct header; //This had extra words
     BodyStruct     message_body;
  };

He then changed the code to this, which got 开发者_开发技巧rid of the extra words:

  struct MyClass
  {

     HeaderStruct header; //This did not have extra words
     BodyStruct     message_body;
  };

None of these types was virtual or derived from anything virtual. So the theory was that perhaps this particular compiler allocated memory for a vptr for the class instances but not for the struct instances. So I'm just trying to determine if such compiler behavior is precluded by the spec.

Thanks!

Ken


By standard 'struct' and 'class' are synonyms that affect only default access to bases and members in class definition.

Standard defines POD (plain old data). POD may not have user defined constructors, destructors, assignment operators, non-static reference members and anything virtual (also non-static members of it should not have such things). PODs have strict memory layout rules (for compatibility with C) and so the implementation can not add there any vtables or RTTI information or the like.

However the C++ compilers of old times did often deviate from standard and from each other quite a bit so your colleague might be right too.


I'm unable to find an online reference for it with a quick search, but I'm pretty sure a compiler is permitted to do ANYTHING with the layout of any class; in particular, in classes without any virtual methods, it's allowed to put a vftp or not, depending on how it's feeling that day, whether it's declared as class or struct (which are equivalent in C++ except for the default access specifier), the phase of the moon, or anything else. The only restriction that I'm aware of is that the top part of a derived object shall match the layout of its first (non-virtual) base class. And I'm not even sure it has to be the first one.

You should not at any time depend on a particular compiler's decision on the layout of an object. Many compilers put a vftp in all objects without exception, in order to provide run-time type information to debuggers, or just to make their own lives easier. Some don't. You have no reasonable way of knowing, except through the sizeof operator.


There's no such thing as a "virtual class". You might mean virtual inheritance, which involves using the virtual keyword before a class name, but the virtual-ness applies to the inheritance relationship, not the class itself. Or maybe you just mean a class that contains virtual functions.

At any rate, the C++ spec doesn't say anything about virtual tables at all; those are specific to an implementation. Typically a virtual table will only be added if the class contains virtual functions, has virtual bases, or inherits from other classes that do. But it would be perfectly valid for an implementation to put a virtual table in every instance of every class.


The virtual modifier for a class is only used if/when you might inherit from the class more than once. In the I/O streams library, istream and ostream both inherit from ios_base, and iostream inherits both istream and ostream. The virtual modifier allows you to inherit twice without getting two copies of the base class members.

But any method can be virtual, even in a non-virtual class -- and therefore any class can have a vtable.

But the real answer to your question :) is that a class and struct are almost identical, except that in a class, members are private by default, whereas in a struct they're public by default.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号