Why are C++ classes allowed to have zero data members?

前端 未结 6 2081
遥遥无期
遥遥无期 2020-12-20 16:46

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

相关标签:
6条回答
  • 2020-12-20 17:26

    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.

    0 讨论(0)
  • 2020-12-20 17:29

    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 讨论(0)
  • 2020-12-20 17:36

    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.

    0 讨论(0)
  • 2020-12-20 17:39

    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.

    0 讨论(0)
  • 2020-12-20 17:43

    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:

    struct TagForward_;
    typedef Tag<TagForward_> ForwardTag;
    
    struct TagRandomAccessible_;
    typedef Tag<TagRandomAccessible_> RandomAccessibleTag;
    

    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.

    0 讨论(0)
  • 2020-12-20 17:48

    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.

    0 讨论(0)
提交回复
热议问题