C++ aggregates have no virtual functions?

為{幸葍}努か 提交于 2021-02-15 20:51:49

问题


In C++, an aggregate is (taken from 8.5.1p1 of the language spec)

an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

So, #1 is not an aggregate, but #2 is an aggregate. Why is #1 not an aggregate aswell?

struct A { virtual void bark() { } int a; }; // #1
struct B { A b; }; // #2

回答1:


Why is #1 not an aggregate aswell?

Because the standard definition of aggregates says that it isn't. The definition says that the class cannot have virtual functions if it is to be considered an aggregate type. That's it. That's the "captain obvious" answer.

Since you quoted the standard definition (and read it, I presume), you know this already, so I must assume that what you are asking is whether there is any fundamental reason why a class with virtual functions cannot be an aggregate type.

Obviously, a class with virtual functions must have it's virtual table pointer (or other mechanism) initialized as part of the compiler-generated constructor. And the only thing that aggregates really provide (in addition to serving as a base definition for PODs and the like) is the ability to do a curly-braced initialization of its data members. I don't see any reason why the compiler could not simply permit the curly-braced initialization syntax while doing the initialization of the virtual table pointer too.

As far as B is concerned, it can be an aggregate because the brace-initialization is possible as long as there is a way to construct the data members from whatever is provided (or not provided) in the initialization list, i.e., it needs each data members to have some (compiler-generated or not) default, copy or move constructor. Remember, the definition of aggregates is shallow as opposed to recursive like the POD definitions (trivial, std-layout), meaning that only the top-level class has those restrictions, not its sub-objects.

The definition of aggregates is obviously very reminiscent of the C struct restrictions, and the brace-initialization for structs is obviously also a feature carried over from C. I believe that for historical reasons, the definition of aggregates was built such that it reflects C structs, and not for reasons of what is or isn't possible for the compiler to do.

I would certainly be of the opinion that there is no good reason for the restriction on aggregates to not have virtual functions. Maybe a proposal should be made to the standard committee to remove this restriction (as it wouldn't break any existing code). Especially now, with unified initialization syntax, aggregates are nothing more than classes where the compiler can generate a constructor with all the data members as parameters (with default values being default-constructed objects). The only other purpose for aggregates is to lump a few of the restrictions that apply to POD classes (trivial, standard-layout, etc.), for which the restriction on not having virtual functions is justified (AFAIK), but that is just a matter of moving that restriction over to PODs.




回答2:


I can't say for sure what was in the committee's minds when they added that restriction to the definition of aggregates. I suspect that it's because they considered that requiring the compiler to also have to set up an instance for virtual function calls (vtable or other) would be sufficiently different from simply initializing values and so added the restriction to simplify the requirements on language implementors.



来源:https://stackoverflow.com/questions/23248505/c-aggregates-have-no-virtual-functions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!