C ++聚合没有虚函数? [英] C++ aggregates have no virtual functions?

查看:66
本文介绍了C ++聚合没有虚函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,聚合是(取自语言规范的8.5.1p1)

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

没有用户提供的构造函数(12.1),没有私有或私有的数组或类(第9条)受保护的非静态数据成员(条款11),没有基类(条款10)和虚拟函数(10.3).

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).

因此,#1 不是聚合,但是#2 是聚合.为什么#1 也不是聚合的?

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.

显然,具有虚函数的类必须将其虚拟表指针(或其他机制)初始化为编译器生成的构造函数的一部分.聚合真正提供的唯一功能(除了充当POD等的基本定义外)是对数据成员进行大括号初始化的能力.我看不出为什么在进行虚拟表指针的初始化时编译器不能简单地允许使用大括号初始化语法的任何原因.

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.

B 而言,它可以是一个聚合,因为只要有一种方法可以通过提供的(或不提供的)构造数据成员,就可以进行花括号初始化.在初始化列表中,即它需要每个数据成员都具有一些(是否由编译器生成)默认,复制或移动构造函数.请记住,聚合的定义是 shallow ,而不是 recursive ,如POD定义(琐碎的std布局),这意味着只有顶级类才具有这些限制,而不是它的子对象.

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.

聚集的定义很明显使人联想到C结构的限制,并且结构的花括号初始化显然也是C继承的功能.我相信由于历史原因,聚集的定义是这样建立的:反映C结构,而不是出于编译器无法执行的原因.

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.

我当然认为没有充分的理由限制聚合不具有虚拟功能.也许应该向标准委员会提出删除此限制的建议(因为它不会破坏任何现有代码).尤其是现在,使用统一的初始化语法,聚合只不过是类,在这些类中,编译器可以使用所有数据成员作为参数来生成构造函数(默认值为默认构造的对象).聚合的唯一其他目的是将一些适用于POD类的限制(琐碎的,标准布局等)放在一起,对于没有虚拟功能的限制是合理的(AFAIK),但这仅仅是一个限制.将限制转移到POD上的问题.

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.

这篇关于C ++聚合没有虚函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆