为什么允许C ++类拥有零数据成员?

时间:2010-08-01 17:05:02

标签: c++

关于c ++的问题 为什么类定义中的最小数据成员数为零

我认为它应该是一个,即指向编译器

定义的虚拟表的指针

非常感谢

6 个答案:

答案 0 :(得分:22)

在继承层次结构中使用没有数据成员的类通常很有用。

基类可能只有多个typedef个用于多个类。例如,std::iterator类模板只定义了标准类型,因此您无需在每个迭代器类中定义它们。

接口类通常没有数据成员,只有虚拟成员函数。

虚拟表与类的数据成员无关。

答案 1 :(得分:5)

嗯,实际上C ++要求所有类必须占用一些空间(您需要能够生成指向该类的指针)。如果类是多态的,它们只需要一个指向vtable的指针。在一个单形类中没有任何理由可以使用vtable。

答案 2 :(得分:5)

我正在开发一个有时甚至使用类型的库 - 喘气! - 甚至不是定义的,更不用说数据成员了!

即,类型不完整,例如

struct foobar;

这用于创建一个明确的名称,仅此而已。

那么这对什么有用呢?好吧,我们使用它来创建不同的标签,使用额外的(空的,但完全定义的)类型:

template <typename TSpec>
struct Tag { };

现在你可以像这样创建不同的标签:

struct TagForward_;
typedef Tag<TagForward_> ForwardTag;

struct TagRandomAccessible_;
typedef Tag<TagRandomAccessible_> RandomAccessibleTag;

这些反过来可用于消除特殊重载的歧义。许多STL实现都做了类似的事情:

template <typename Iter>
void sort(Iter begin, Iter end, RandomAccessibleTag const&) …

严格地说,通过公共Tag类模板的间接路由是多余的,但是为了文档起见它是一个有用的技巧。

所有这些只是为了表明(严格的,静态的)类型系统可以以多种不同的方式使用,而不仅仅是捆绑和封装数据。

答案 3 :(得分:0)

没有数据成员的类的另一个用途是用于处理来自其他来源的数据。所有内容都在运行时通过指针或引用传递给类,并且类对数据进行操作但不存储任何数据。

直到我看到它在我接受的UML课程中完成之前,我才真正想过这个。它有它的用途,但它通常会创建耦合类。

答案 4 :(得分:0)

因为类不是结构。与流行的看法相反,他们的目的是来保存数据。

例如,考虑一个验证器基类,它定义一个传递字符串以进行验证的虚方法,并返回一个bool。

验证器的实例可以拒绝其中包含大写字母的字符串。这是一个关于何时应该使用类的完美示例,并且通过定义它的作用,显然没有理由拥有任何成员变量。

答案 5 :(得分:0)

  

关于c ++的问题,为什么类定义中的最小数据成员数为零

它是零,因为你有各种不应该有成员的类:

例如,您可以实现仅包含静态函数的traits类。这些类相当于namespace,也可以识别为类型。这意味着您可以在类上实例化模板,并确保该模板的实现使用类中的函数。 此类特征类的大小应为零。

示例:

class SingleThreadedArithmetic
{
    static int Increment(int i) { return ++i; }
    // other arithmetic operations implemented with no thread safety
}; // no state and no virtual members -> sizeof(SingleThreadedArithmetic) == 0

class MultiThreadedArithmetic
{
    static int Increment(int i) { return InterlockedIncrement(i); }
    // other arithmetic operations implemented with thread safety in mind
}; // no state and no virtual members -> sizeof(MultiThreadedArithmetic) == 0

template<class ThreadingModel> class SomeClass
{
public:
    void SomeFunction()
    {
        // some operations
        ThreadingModel::Increment(i);
        // some other operations
    }
};

typedef SomeClass<SingleThreadedArithmetic> SomeClassST;
typedef SomeClass<MultithreadedArithmetic>  SomeClassMT;

您可以通过实现“标记”类来定义不同的类类别:不包含接口或数据的类,但仅用于区分不同的“逻辑”类型的派生类。区分可以用于普通OOP代码或模板化代码。 这些“标签”类也有0个大小。有关示例,请参阅当前STL库中的iterators标记实现。

我确信在其他情况下您可以使用“零大小”类。