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

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

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.

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.

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.

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.

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.

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.

Related

How to detect if a class has member variables?

Problem
I would like to detect if a class has member variables and fail a static assert if they do. Something like:
struct b {
int a;
}
static_assert(!has_member_variables<b>, "Class should not contain members"). // Error.
struct c {
virtual void a() {}
void other() {}
}
static_assert(!has_member_variables<c>, "Class should not contain members"). // Fine.
struct d : c {
}
static_assert(!has_member_variables<d>, "Class should not contain members"). // Fine.
struct e : b {
}
static_assert(!has_member_variables<e>, "Class should not contain members"). // Error.
struct f : c {
char z;
}
static_assert(!has_member_variables<f>, "Class should not contain members"). // Error.
Is there a way to achieve this with SFINAE template? This class may have inheritance or even multiple inheritance with virtual functions (no members in the base classes though).
Motivation
I have a pretty simple setup as follows:
class iFuncRtn {
virtual Status runFunc(Data &data) = 0;
};
template <TRoutine, TSpecialDataType>
class FuncRoutineDataHelper : public iFuncRtn {
Status runFunc(Data &data) {
static_assert(!has_member_variables<TRoutine>, "Routines shouldnt have data members!");
// Prepare special data for routine
TSpecialDataType sData(data);
runFuncImpl(sData);
}
class SpecificRtn :
public FuncRoutineDataHelper<SpecificRtn, MySpecialData> {
virtual Status runFuncImpl(MySpecialData &sData) {
// Calculate based on input
sData.setValue(someCalculation);
}
};
The FunctionalityRoutines are managed and run on a per tick basis. They are customized and can perform a wide variety of tasks such as contacting other devices etc. The data that is passed in can be manipulated by the routine and is guaranteed to be passed in on each tick execution until the functionality is finished. The right type of data is passed in based on the DataHelper class. I wan't to discourage future people from mistakenly adding data to the functionality routines as it is very unlikely to do what they expect. To force this, I was hoping to find a way with static assert.
You can solve this by depending on the compiler doing empty base class optimizations, by checking if a class derived from your T has the same size as an empty class with virtual functions:
template<typename T, typename... BaseClasses>
class IsEmpty
{
// sanity check; see the updated demo below
static_assert(IsDerivedFrom<T, BaseClasses...>::value);
struct NonDerived : BaseClasses... { virtual ~NonDerived() = default; };
struct Derived : T { virtual ~Derived() = default; };
public:
inline static constexpr bool value = (sizeof(NonDerived) == sizeof(Derived));
};
This should work with both single and multiple inheritance. However, when using multiple inheritance, it's necessary to list all base classes, like that:
static_assert(IsEmpty<Derived, Base1, Base2, Base3>::value);
Obviously, this solution rules out final classes.
Here's the updated demo.
Here's the original demo. (doesn't work with multiple inheritance)
You will have to mark the classes in some way or another. Pick a way you are comfortable with, a property or some kind of type integer member with an enum. Whoever makes sub-classes will have to follow your convention to make it work.
All other answers here will be some variant of this.
Any answer that uses a sizeof could not guarantee this will work between platforms, compilers, or even classes on the same platform and compiler, due to easily being able to fit a new member inside the default class member alignment, where the sizes of sizeof could easily end up the same for a sub-class.
Background:
As stated in your code and question, all of that is just plain and basic C ad C++ code, and is resolved entirely at compile time. The compiler will tell you if a member exists or not. After its compiled it's a mash of efficient, nameless, machine code with no hints or help for that kind of thing by itself.
Any name you use for a function or data member effectively disappears, as you know it and see it there, after compile and there is no way to lookup any member by name. Each data member is known only by its numerical offset from the top of the class or struct.
Systems like .Net, Java, and others are designed for reflection, which is the ability to remember class members by name, where you can find them at runtime when you program is running.
Templates in C++, unless mixed mode C++ on something like .Net, are also all resolved at compile time, and the names will also all be gone, so the templates by themselves buy you nothing.
Languages like Objective-C also are written to not fail necessarily if certain types of special members are missing, similar to what you are asking, but under the covers its using a lot of supporting code and runtime management to keep track independently, where the actual function itself and its code are still unware and rely on other code to tell them if a member exists or to not fail on null member.
In pure C or C++ you will need to just make your own system, and be literal about tracking dynamically what does what. You could make enums, or lists or dictionaries of name strings. This is what is normally done, you just have to leave hints for yourself. A class cannot be compiled in a way that gives implicit visibility to future sub-classes by definition, without using some form if RTTI.
Its common to put a type member on a class for this very reason, which could be a simple enum. I would not count on sizes or anything that might be platform dependent.

c++ function cannot derive template for child class of base class with templates

I am somewhat new to templates and I don't understand how the compiler derives the templates for child classes when I inherit from the base class in a way where I set the templates.
I am creating a genetic algorithm base class for which I have written an abstract base class for the individuals of a population. I want to have a general definition so I use templates to define the fenotype and genotype:
template<typename T, typename S>
class individual {
public:
individual(S& fenotyp, T& genotyp) :
fenotype(fenotyp), genotype(genotyp) {}
...
S fenotype;
T genotype;
...
};
When the individuals are bitstrings, I have the following child class:
class bitstring_individual : public individual<boost::dynamic_bitset<>,
boost::dynamic_bitset<>> {
public:
using individual::individual;
...
};
Now I no longer have to work with template brackets anymore. Further down the line, I have a function that given a population std::vector<individual<T,S>>, returns the half with the highest fitness. This works on any type of individual so we can keep the definition general:
template<typename T, typename S>
std::vector<individual<T,S>> select_best_half(std::vector<individual<T,S>> parents,
std::vector<individual<T,S>> children) {
...
}
However, if I call this function I get error: no matching function for call to select_best_half(...) and the compiler says template argument deduction/substitution failed: and mismatched types ‘individual<T, S>’ and ‘bitstring_individual'.
In the definition of bitstring_individual we see that:
bitstring_individual : individual<boost::dynamic_bitset<>,boost::dynamic_bitset<>>
so why does the compiler not understand that the templates should be boost::dynamic_bitset<>? Can someone help me understand how the compiler tackles this inheritance and how can I fix it?
(using bitset = boost::dynamic_bitset)
Your bitstring_individual is not the same as individual<bitset, bitset>, and the compiler rightfully does not recognize them as such. One inherits the other, yes, but that does not make them interchangeable everywhere - in particular when used as template arguments.
In short: vectors (and other containers) of different (even polymorphically related) types are not covariant. Just like you cannot pass a std::vector<int> to a function expecting a std::vector<long> you cannot pass a std::vector<bitstring_individual> where a std::vector<individual<bitset, bitset>> is expected.
Note: Yes, they are different conversions, but the idea is the same.
Imagine that sizeof(individual<bitset, bitset>) = 32 and that bitstring_individual adds some members so that sizeof(bitstring_individual) = 48. If the compiler deduced T = S = bitset, then it would generate a method signature containing std::vector<individual<bitset, bitset>>, so a vector whose elements have size 32. But when you try to call it, you are passing a vector whose elements have size 48. Those vectors are not covariant, which would invariably lead to problems.
If you want your concrete individuals to have no other functionality than what the templated base class provides, just do this:
using bitstring_individual = individual<bitset, bitset>;
Otherwise, your vectors cannot store the individuals directly - you would have to use something like std::vector<std::shared_ptr<individual<T, S>>> (alternatively unique_ptr or ref instead of shared_ptr) for all population vectors.
Your question actually deals with covariance and contravariance of (certain) types in C++. Even if you were to "hard-code" your template parameters, i.e. have:
using i_bs_bs = individual<bitset, bitset>;
using std::vector;
class bitstring_individual : public i_bs_bs { ... };
vector<bsi> select_best_half(vector<i_bs_bs> parents, vector<i_bs_bs> children) {
...
}
You'd still get an error passing a vector<bitstring_individual> to select_best_half(). Why? Because, in C++ std::vector<T> is not a covariant type constructor.
To take the the example from the linked-to Wikipedia page, Suppose your inheriting classes were Animal (base class) and Cat (derived class). In C++, you can't add an Animal to a vector of Cats. All elements of that vector need to be Cats. Similarly, and as #MaxLanghof's answer explains, you can't add a bitstring_individual to a vector whose elements are of bitstring_individual's base type. Any special behavior necessary for handling bitstring_individual would simply not apply to the elements of a vector<i_bs_bs>.

C++ a class inherit from a type

I created a type, which is a list of priority queues of strings (not my idea, I have to do it):
typedef list<priority_queue<string>> L;
L myList;
Now I need to create a class M, which will inherit from this type. From what I acknowledged, I need to use templates to do so, but I still have no idea how to do it and I haven't found anything online.
How do I make a class inherit from a type?
It's as simple as:
class foo : L { // Note this is private inheritance
};
The type alias is just a name for another type, not a type in its own right. Since std::list is a class template and L names a complete specialization, you can just do it.
Just be sure not to use it in any polymorphic way that involves deleteing a pointer to a std::list. It's not designed for it, since it lacks a virtual destructor.

Avoiding proliferation of templates

I am working on a fairly tightly coupled library which up until now has explicitly assumed all computations are done with doubles. I'm in the process of converting some of the core classes to templates so that we can start computing with std::complex<double>. I've templated about 10 of our classes so far have noticed a tendency toward proliferation of templates. As one class becomes templated, any other class that uses the templated class appears to need templating as well. I think I can avoid some of this proliferation by defining abstract base classes for my templates so that other classes can just use pointers to the abstract class and then refer to either a double or std::complex<double> version of the derived class. This seems to work on at the header level, but when I dive into the source files, the templated class will often have functions which compute a value or container of values of type double or std::complex<double>. It seems like a waste to template a whole class just because a couple of lines in the source file are different because of some other classes return type.
The use of auto seems like a possible way to fix this, but I'm not 100% sure it would work. Suppose I have an abstract base class AbstractFunction from which Function<Scalar> derives, where Scalar can be double or std::complex<double>. Now suppose we have two member functions:
virtual Scalar Function<Scalar>::value(double x);
virtual void Function<Scalar>::values(std::vector<Scalar> &values, std::vector<double> x);
And suppose I have some other class (that I don't want to template) with a member function that calls one of these.
// populate double x and std::vector<double> xs
auto value = functionPtr->value(x);
std::vector<auto> values;
functionPtr->values(values, xs);
// do something with value and values
where functionPtr is of type std::shared_ptr<AbstractFunction>.
I could see auto working for the first case, but I don't believe I could construct a vector of auto to be filled with the second one. Does this necessitate making the calling class a template? Can someone recommend another strategy to cut down on the proliferation of templates?
I think you are already wrong in assuming that the first use-case is going to work. If you have an abstract base class, then either value is a member of it and you can call it through std::shared_ptr<AbstractFunction> or value is not a member of it and only available if you know the derived class' type. In the first case, the AbstractFunction::value method must have a fixed return type, it can not depend on Scalar, which is the template parameter of the derived class.
That said: In my experience the two concept often don't mix well. You either want to create an abstract base class with the full interface or you want a template. In the latter case, there is often no need / no benefit for having an abstract base class. It then follows that also the code using your template works with templates.
What might help you is to "export" the template parameter from Function, i.e.
template<typename T>
class Function
{
public:
using value_type = T;
value_type value() const;
// ...
};
and in other parts of the code, use a template which takes any T which behaves like Function if you don't want to directly write out (and limit yourself) to Function:
template<typename T>
void something( const std::shared_ptr<T>& functionPtr )
{
// ignoring where x comes from...
using V = typename T::value_type;
V value = functionPtr->value(x);
std::vector<V> values;
functionPtr->values(values, xs);
}
Note that this is just one option, I don't know if it is the best option for your use-case.

Internal class declaration [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pros and cons of using nested C++ classes and enumerations?
Consider the following declaration.
class A {
public:
class B{
};
};
Nothing special.
But what are the benefits of this?
What reasons may there be for putting one class inside of another?
There is no inheritance benefit between both classes.
If B is put inside of A for its private names sharing, then A is for B just a namespace, and there is reason to make B private, too.
What do you think about this?
Conceptually, it lets the programmer(s) know that class B relates specifically to class A. When you use class B outside of class A, you must use the type as A::B, which reminds you, every time, that B is related to A. This doesn't add any functionality, but shows a relationship.
Similarly, you don't have to use inheritance/composition, or classes at all. You can more or less simulate classes in C just by using structs and functions. It's just a way to keep the code cleaner and more straightforward and let the programmer relate the code to the design more easily. Classes accomplish this much more than public subclasses do, but that's just an example.
If it's a private/protected subclass (which I see it isn't in your example), then that obviously limits that class to the implementation of that class and that class's children, which might be desired (again design-wise) if the only use case of that class is in the implementation of that class (and possibly its children).
Benefit 1: The namespace aspect
Indeed, A provides a namespace for B, and this can help us structure our code much better. Consider a concrete example with vector for A, and iterator for B. Arguably,
class vector {
public:
class iterator { /*...*/ };
iterator begin() { /*...*/ }
};
is easier to type, to read, and to understand than
class vector_iterator {
/*...*/
};
class vector {
public:
vector_iterator begin() { /*...*/ }
};
Observe, in particular:
When the two classes (vector and iterator) depend on each other, i.e. use each other's members, the second version above would require one of the two to be forward-declared, and in some cases mutual type-dependencies might lead to unresolvable situations. (Using nested classes, it is much easier to avoid such problems, because within most parts of the nested class definition, the outer class is considered completely-defined. This is due to §9.2/2.)
You may very well have many other data types that maintain their own iterator, e.g. linked_list. Using the second version above, you'd need to define linked_list_iterator as a separate class. Class names would get ever longer and complicated the more of these 'dependent' types and alternative types you added.
Benefit 2: Templates
Continuing the example above, consider now a function template that takes a container (such as vector and linked_list defined above) as arguments and iterates over them:
template <typename Container>
void iterate(const Container &container) {
/*...*/
}
Inside this function, you'd obviously very much like to use the iterator type of Container. If that is a nested type, it's easy:
typename Container::iterator
But if it isn't, you would have to take the iterator type as a separate template parameter:
template <typename Container, typename Iterator>
void iterate(const Container &container) {
/*...*/
Iterator it = container.begin();
/*...*/
}
And if that iterator type does not appear among the function arguments, the compiler could not even guess the type. You'd have to explicitly add it in angle brackets each time you call the iterate function.
Final notes: None of this has much to do with whether the nested class is declared as public or private. My examples above suggest a situation in which a public nested type is clearly preferrable, because I suppose the iterator type should be able to be used outside the container class.
What reasons may be for putting one class inside of another one?
If you need to restrict the scope of B to only available for A, then internal class definition helps. Because it restricts the class scope to local.This is call scope localization.These are in more generic term called inner class declaration. Check this link.
This stackoverflow question helps you understand more.