类声明使类成为不完整的类型,因此不能定义类的任何对象。并且不完整类型的定义是其成员未指定。这是不是意味着一个空体的类没有在其定义中指定成员使它成为一个不完整的类型?
class Empty { };
Empty e1; // okay, but why?
答案 0 :(得分:4)
具有空体的类是不完整类型吗?
不,具有空体的类只是一个空类,但仍然是一个完全定义的类。不完整类型是一种完全定义不可见的类型。
class Empty;
// Here, Empty is an incomplete type
class Empty { };
// Here, Empty is a complete type
根据C ++ 11标准的第3.9 / 5段:
已声明但未定义的类,或未知大小或元素类型不完整的数组, 未完全定义的对象类型。未完全定义的对象类型和void类型不完整 类型(3.9.1)。对象不应被定义为具有不完整的类型。
另外,根据第9.2 / 2段:
在类说明符的结束
}
,类被视为完全定义的对象类型(3.9)(或完整类型)。 [...]
答案 1 :(得分:1)
正如其他人所说,这不是一个不完整的类型。在C ++中,有时候这种事情是可取的。
请考虑以下事项:
template<class T>
class Field
{
public:
virtual std::string toString() const = 0;
};
如何将其存储在一个集合中?答案是,我不能。但我能做到:
class FieldBase
{
public:
virtual ~FieldBase() = 0 { }; // virtual destructor needed, but no other members
virtual std::string toString() const = 0;
};
现在,从技术上讲,根据您的问题,没有定义任何成员。这是抽象的。它无法实例化。但现在我们可以做到:
template<class T>
class Field : public FieldBase
{
virtual std::string toString() const { /* ... */ };
};
我知道这稍微偏离了你原来的问题,但它确实说明基类没有定义(除了intent),我们现在可以将这些模板类存储在std::vector<FieldBase*>
集合中。
答案 2 :(得分:0)
是的,这是一个完整的类型。当我上次检查时,大小是一个字节(至少在MS的编译器上)。
为了创建一个不完整的结构,省略大括号:
struct Empty;
这也称为前向声明结构,并不是结构的定义。