9

question about c++ why minimal number of data members in class definition is zero

i think it should be one , i.e pointer to virtual table defined by compiler

thanks a lot

James McNellis
  • 348,265
  • 75
  • 913
  • 977
user408015
  • 91
  • 1
  • 2
  • 7
    not all classes have a vtable, so that's irrelevant. – tenfour Aug 01 '10 at 17:06
  • 7
    Nor do vtables have anything to do with C++. They are just a common implementation technique (and thus nothing to do with the language) for implementing inheritance (but not the only one). – Martin York Aug 01 '10 at 17:43
  • 4
    The obvious question I would ask is why not allow zero sized objects. The fact that it is unique type has information that can be used. – Martin York Aug 01 '10 at 17:46
  • 4
    Why should the class *not* be allowed to have zero data members? – jalf Aug 01 '10 at 19:31

6 Answers6

24

It is often useful to have a class with no data members for use in inheritance hierarchies.

A base class may only have several typedefs that are used in multiple classes. For example, the std::iterator class template just has the standard types defined so that you don't need to define them in each iterator class.

An interface class typically has no data members, only virtual member functions.

A virtual table has nothing to do with the data members of a class.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
7

I’m working on a library that sometimes even uses types that – gasp! – aren’t even defined, much less have data members!

That is, the type is incomplete, such as

struct foobar;

This is used to create an unambiguous name, nothing more.

So what is this useful for? Well, we use it to create distinct tags, using an additional (empty, but fully defined) type:

template <typename TSpec>
struct Tag {};

Now you can create distinct tags like so (yes, we can declare the type inside the template argument list, we do not need to declare it separately):

using ForwardTag = Tag<struct Forward_>;
using RandomAccessibleTag = Tag<struct RandomAccessible_>;

These in turn can be used to disambiguate specialized overloads. Many STL implementations do something similar:

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

Strictly speaking, the indirect route via a common Tag class template is redundant, but it was a useful trick for the sake of documentation.

All this just to show that a (strict, static) type system can be used in many different ways than just to bundle and encapsulate data.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 2
    are those names just to illustrate the example? Names with leading underscore followed by upper-case characters are reserved to the implementation :) – jalf Aug 01 '10 at 19:35
  • @jalf: the names were just for illustration. But you’re right, here, let me change them. – Konrad Rudolph Aug 02 '10 at 16:38
5

Well, actually C++ mandates that all classes must occupy some space (You need to be able to generate a pointer to that class). They only need a pointer to a vtable though, if the class is polymorphic. There's no reason for a vtable at all in a monomorphic class.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • @Billy i thought there is only a vtbl if you have virtual functions? – InsertNickHere Aug 01 '10 at 17:12
  • 1
    @InsertNickHere: That's what polymorphic means. – Billy ONeal Aug 01 '10 at 17:12
  • @Billy Dident know that there is always a virtual function since im not that used to c++. – InsertNickHere Aug 01 '10 at 17:31
  • @InsertNickHere: What? There's not always a virtual function. It's just that a class is polymorphic if and only if it contains virtual function(s). That's not a C++ thing, that's a general OOP thing. – Billy ONeal Aug 01 '10 at 17:32
  • 2
    May I ask what a meromorphic class is? – Maciej Hehl Aug 01 '10 at 17:44
  • 3
    I don't think that the specs mandate that a class have a size (might be wrong on that). What it does mandate is that every object have a unique address. The simplest implementation technique for this is to make sure that every class has a size greater than zero (otherwise you would need special processing for zero sized objects to make sure they all had unique addresses). – Martin York Aug 01 '10 at 17:45
  • 1
    @Maciej: Thanks for catching the typo :) (I meant monomorphic) @Martin: How can an object have an address without a size? What would new MyObject[45] return? – Billy ONeal Aug 01 '10 at 18:40
  • @Macielj Well... ironically enough meromorphic functions do exist, just not in programming as far as I know. In math, meromorphic means complex differentiable. The CS Category Theorists might know how to extend that definition to talk about types. – archgoon Aug 01 '10 at 19:25
  • @LokiAstari I'm afraid you're wrong, as the Standard does mandate that: `[Classes] §9/3 Complete objects and member subobjects of class type shall have nonzero size` via http://stackoverflow.com/a/8271750/2757035 – underscore_d Jan 31 '16 at 22:49
  • 1
    @underscore_d: Yep. [What is the size of empty class in C++](http://stackoverflow.com/a/4789929/14065) – Martin York Jan 31 '16 at 23:07
  • With rep like yours, I should've known you'd already answered it somewhere else ;-) – underscore_d Jan 31 '16 at 23:40
0

Another use of a class with no data-members is for processing data from other sources. Everything gets passed into the class at runtime through pointers or references and the class operates on the data but stores none of it.

I hadn't really thought about this until I saw it done in a UML class I took. It has it's uses, but it does usually create coupled classes.

0

Because classes are not structures. Their purpose, contrary to popular belief, is not to hold data.

For instance, consider a validator base class that defines a virtual method which passes a string to validate, and returns a bool.

An instance of a validator may refuse strings which have capital letters in them. This is a perfect example on when you should use a class, and by the definition of what it does, there's clearly no reason to have any member variables.

kyoryu
  • 12,848
  • 2
  • 29
  • 33
0

question about c++ why minimal number of data members in class definition is zero

It is zero because you have various cases of classes that should have no members:

You can implement traits classes containing only static functions for example. These classes are the equivalent of a namespace that is also recognizable as a type. That means you can instantiate a template on the class and make sure the implementation of that template uses the functions within the class. The size of such a traits class should be zero.

Example:

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;

You can define distinct class categories by implementing "tag" classes: classes that hold no interface or data, but are just used to differentiate between separate "logical" types of derived classes. The differentiation can be used in normal OOP code or in templated code. These "tag" classes have 0 size also. See the iterators tags implementation in your current STL library for an example.

I am sure there are other cases where you can use "zero-sized" classes.

utnapistim
  • 26,809
  • 3
  • 46
  • 82