Reputation: 41
If you want to wrap some enum type with a class, e.g., to build some functions around it, you could end up with the following situation:
main.cpp:
#include "WrappedEnumConstants.h"
int main(int argc, char * argv[])
{
WrappedZero.print();
WrappedOne.print();
}
WrappedEnumConstants.h
#ifndef WRAPEDENUMCONSTANTS_H
#define WRAPEDENUMCONSTANTS_H
#include "WrappedEnum.h"
#include "InternalEnum.h"
static const WrappedEnum WrappedZero(ZeroEnum);
static const WrappedEnum WrappedOne(OneEnum);
#endif
WrappedEnum.h
#ifndef WRAPPEDENUM_H
#define WRAPPEDENUM_H
#include <iostream>
#include "InternalEnum.h"
class WrappedEnum
{
public:
WrappedEnum(InternalEnum a);
void print() const;
private:
InternalEnum a;
};
#endif
WrappedEnum.cpp
#include <iostream>
#include "WrappedEnum.h"
WrappedEnum::WrappedEnum(InternalEnum a) :
a(a)
{}
void WrappedEnum::print() const {
std::cout << "WrappedEnum: " << a << std::endl;
}
InternalEnum.h
#ifndef INTERNALENUM_H
#define INTERNALENUM_H
enum InternalEnum { ZeroEnum, OneEnum};
#endif
The output I get is like expected:
WrappedEnum: 0
WrappedEnum: 1
I am wondering if initialization of the static constants WrappedZero and WrappedOne is safe. Are the constants of ZeroEnum and OneEnum guaranteed to be initialized before WrappedZero and WrappedOne or was I only lucky? Especially, I am wondering what pitfalls there might be if you used the WrappedEnum in a large project with many things linked together. Do you see any?
Are there differences in initialization of enum constants (like ZeroEnum and OneEnum) and a global "static const int"?
Upvotes: 2
Views: 446
Reputation: 114491
Yes there is a difference.
A field of enum type in an instance is for the compiler unknown at compile time so when generating code it's forced to actually access the instance to find the value and the generated code will be bigger and slower.
A const int
can instead be known at compile time (if you initialize it with a constant) and so the compiler can generate code that uses directly the value (and you can also use that as a constant expression for example in array declarations or templates).
Also note that wrapping your values in static-duration instances you're creating problems for who will use those wrapped values during the initialization of other static duration instances because the order of initialization is not guaranteed.
I'm not really sure why you think it's a good idea to wrap a box that contains what you need in a bag. Except writing a lot more code and annoying the compiler and your users, what good thing are you achieving doing that?
Upvotes: 0
Reputation: 254471
Are the constants of ZeroEnum and OneEnum guaranteed to be initialized before WrappedZero and WrappedOne or was I only lucky?
They are compile-time constants, so are not initialised at runtime at all. It's safe to use them at any time.
Are there differences in initialization of enum constants (like ZeroEnum and OneEnum) and a global "static const int"?
If the static const int
is initialised with a constant value, it will be a compile-time constant in any code that knows its value. Otherwise, it will be initialised during the static initialisation phase, before the program starts. In either case, it's also safe to use it at any time.
If it needs to be initialised with a run-time value, then it will be initialised during the dynamic initialisation phase (like your "wrapped" objects), and you may encounter problems with the initialisation order.
Upvotes: 1