I am trying to do a simple class to unique ID conversion. I am thinking about adding a static method:
class A {
static int const *GetId() {
static int const id;
return &id;
}
};
Each class would then be identified by unique int const *. Is this guaranteed to work? Will the returned pointer really be unique? Is there any better simpler solution?
I have also thought about pointer to std::type_info:
class A {
static std::type_info const *GetId() {
return &typeid(A);
}
};
Is that better?
Edit:
I don't need to use the id for serialization. I only want to identify a small set of base classes and I want all subclasses of some class to have the same id
Yes, this will work. Each static local will be given distinct memory location at the time when the module is loaded and it will persist until the module is unloaded. Remember, static locals are stored in static storage that is distributed during compilation and they persist till the module gets unloaded, so they will have distinct memory locations.
The address of static variable is guaranteed to be unique and the same in all translation units.
It is not a good idea because it requires you to add code to every class to be identified.
The pointers to type info objects are not guaranteed to be unique, but the type info objects themselves are guaranteed to compare as equal for a given class, and as unequal for distinct classes. This means you can use small wrapper objects that carry type info pointers, and the delegate the comparisions to the type info objects. C++11 has such a wrapper in the standard library, and if you don't have access to that, there is one in Andrei Alexandrescu's "Modern C++ Design", and therefore probably also in the Loki library, there is probably one in Boost, and there is one on my Wordpress blog – it's not like you to have invent one from scratch.
If, however, the id's are to be used for serialization, then you need id's that are valid across builds. And in that case you you need strings or UUIDs. I would go with UUIDs.
To associate a class with an UUID you can in general use a type traits class. Or if you're only doing Windows programming then you can use Visual C++'s language extensions for this. I think but I am not 100% sure that those language extensions are also implemented by g++ (in Windows).
Cheers & hth.
As I have noticed at least MSVC 2008 or 2010 optimizes the static variable, so that the following GetId function returns same address even for different classes.
static int const *GetId() {
static const int i = 0;
return &i;
}
Therefore address of uninitialized constant static variable may not be used for identification. The simplest fix is to just remove const:
static int *GetId() {
static int i;
return &i;
}
Another solution to generate IDs, that seems to work, is to use a global function as a counter:
int Counter() {
static int i = 0;
return i++;
}
And then define the following method in the classes to be identified:
static int GetId() {
static const int i = Counter();
return i;
}
As the method to be defined is always the same, it may be put to a base class:
template<typename Derived>
struct Identified {
static int GetId() {
static const int i = Counter();
return i;
}
};
And then use a curiously recurring pattern:
class A: public Identified<A> {
// ...
};
The address of the static int is guaranteed to be unique for each
function (and the same for every call to the same function). As such,
it can work very well as an id within a single execution of the code.
The address could conceivably change from one run to the next, and will
often change from one compilation to the next (if you've changed
anything in the code), so it is not a good solution for an external id.
(You don't say whether the id must be valid outside a single execution
or not.)
The address of the results of a typeid is not guaranteed to be the
same each time you call the function (although it probably will be).
You could use it to initialize a pointer, however:
static std::type_info const& GetId()
{
static std::type_info const* id = &typeid(A);
return id;
}
Compared to using int*, this has the advantage of providing additional
information (e.g. for debugging). Like int*, the identifier may be
different from one run to the next; A::GetId()->name() will point to
the same '\0' terminated string (although again the address might be
different) provided you compile with the same compiler. (As far as I
can tell, the standard doesn't guarantee this, but in practice, I think
you're safe.) Change compilers, however, and all bets are off.
The solution I've used in the past is something like:
static char const* GetId()
{
return "A"; // Or whatever the name of the class is.
}
This provides a unique identifier, easily compared, within a single
execution of the code, and a string value which can be used as an
external identifier, and which is guaranteed across all compilers. We
implemented this as a macro, which defined both the static function, and
a virtual function which returned it, e.g.:
#define DECLARE_IDENTIFIER(name) \
static char const* classId() { return STRINGIZE(name); } \
virtual char const* id() { return classId(); }
This results in a very fast (but limited) RTTI, and supports external
identifiers for serialization and persistency.
The int* method would be unique, since a different static memory cell must be allocated for each static variable, and I'd guess it is simpler to understandthan the type_info idea.
Clearly pointers to different variables must have different values. Just watch out if you choose to derive a subclass of A. You need to decide what your policy is for id. If you did nothing then the subclass would have the same id.
In general, you really really want to avoid hacky things like this. If I really had to do this, I'd look at using some UUID system (there's a library in Boost for that, but I'm not very familiar with it), or some singleton that maintained a list of these objects for whatever purpose you need.
Static variables are initialized before Heap & Stack memory so yeah it will be unique.
Quirky though.
Because you will have to add this method to all classes that require a UID you may as well do this.
unsigned int getUID()
{
return 12;
}
The advantage of this is that the compiler will be able to use a jump table if you are using this for RTTI for switching on type, which will not be possible with two pointers because the jump table would be very sparse.
The (minor) disadvantage is you need to keep track of which identifiers have been taken.
A major disadvantage of the first method you presented is that the same numbers cannot be used to identify objects because the virtual getUID() method won't be able to take the address of the variable in another function's scope.
Related
Well, I know the functionality of const data member in a C++ class.
What I want to know is, the purpose of introducing a const data member in a class. Why someone will use that while writing a real software? What are the real-life usage of const data members?
Please give me a few real life examples with reasons.
EDIT :
I am not asking about static const data member.
I am asking for some real life use cases where each object will be having a different const value for same data.
You'd use a const data member for the same reason that you'd use any const object: for a value that may be arbitrarily initialised but then never changed.
A good rule of thumb is to denote something as const "by default", so you can picture plenty of reasons to use it in a class.
class User
{
User(const std::string& name)
: name(name)
{}
private:
/**
* User's name is an invariant for the lifetime of this object.
*/
const std::string name;
};
Can you leave out the const here? Yeah, sure. But then you may accidentally change name when you didn't mean to. The entire purpose of const is to protect against such accidents.
However, sadly, your class will not be assignable!
There are several cases. The most obvious one is a static const data member. These are used as scoped constants:
class Something {
static const int SOME_CONSTANT = 17;
};
Note that under C++11 and onward, constexpr usually makes more sense in those cases.
This defines a constant that is typed and scoped to the class' implementation. I suspect this was not what you were asking, however.
The more interesting use case is for values that are different between instances of the class, but constant across the class' lifetime.
For example, suppose you have a RAID implementation, where a configuration sets the stripe width. You do not know the stripe width at compile time, so the above construct will not help you. You do want the width to remain constant throughout the class' lifetime however (maybe your code doesn't know how to handle stripe width changes).
In those cases, marking the value const, and setting it in the constructor, can give you compile time guarantee that no one is changing this value.
You use it exactly the same as you would use a globally declared const, only you want it to only apply to the class you have defined it in. For example
class Character
{
public:
Character()
:
mCurrentHealth{TOTAL_HEALTH},
mCurrentMana{TOTAL_MANA}
{
}
// Define lose/gain health/mana functions
// for mCurrentHealth and mCurrentMana
private:
int mCurrentHealth;
int mCurrentMana;
// Constants
const int TOTAL_HEALTH = 100;
const int TOTAL_MANA = 50;
};
There are many other examples, but the main point is that we don't want TOTAL_HEALTH and TOTAL_MANA defined outside the class, because they won't be relevant.
Goal:
I have many derived classes (later on there will probably be additional derived classes) which are stored inside a tree structure and I want to serialize each of those classes into a protobuffer and later encrypt the binary data (given by SerializetoArray).
But each of those classes should be encrypted with a different key. So obviously if I want to decrypt it I need to know which key was used to encrypt.
Question:
Is there a easy way to assign a unique integer to each of those classes, so that the number is the same across runtimes on every system (Linux, MacOS, Windows etc.) and for every instance of the class? (It should also not change if the class gets a version update.)
One obvious solution would be to define a number manually, but that will be unpractical later on, since I hope that many of those derived classes will be designed by the community and thus it would be almost impossible to guarantee the uniqueness of them.
Is there a better solution?
Here's my two cents:
Add a static const member variable to each class, with the desired value.
That way, each instance of the same class will always have the very same value.
something like:
class MyClassA
{
static const int myVal = 1;
public:
inline myVal() const { return myVal; }
}
class MyClassB
{
static const int myVal = 2;
public:
inline myVal() const { return myVal; }
}
To avoid duplicated values you might create assign them from an enum, for instance.
Before I start, this is not a style opinion question. I want to know why and if I really have to place storage modifiers before the function. Philosophical discussion follows.
A very friendly C++ grammar policeman once taught me always to place modifiers to objects after the doodad to be modified. For example:
int const myint; // good
const int myint; // bad
The idea of this, and I quite like his or her reasoning, is that the modifier will then always modify the property before it. So when we declare a method the logical convention is this:
const int const fun(); // bad
int const fun() const; // good
So assuming that this is the way I do things, and without starting a debate on this all over again, why do I have to place storage modifiers (such as static) before the function? So a const and static function next to each other will confusingly look like this:
int fun1() const;
static int fun2();
Given that, conceptually, the static and const keywords in this context have categorically related roles (they both modify what the function can and cannot do, to be broad) shouldn't similar grammar rules apply to them? I want to be able to do this:
int fun1() const;
int fun2() static; // why doesn't this work?
The reason is that static is an entirely different sort of thing from const.
Specifically, static specifies a storage class, while const is a cv-qualifier (or just qualifier, depending on the standard you're looking at).
As such, the rules for the two are rather different. As you've already found, one of the rules is that a storage class specifier needs to be nearly the first item in the declaration, and that only one storage class can be specified in most declarations (the sole exception of which I'm aware: you can specify thread_local along with either static or extern).
There is a big difference between declaring a static or virtual function and func() const, in that the first defines how the the function interacts to the object it is a member of, and the second form defines what it is allowed to do TO the object it is a member of.
And, yes, it's slightly confusing that one comes after the function prototype, and the other is before. I think that is because it would be even more confiusing if const char * const x = "abc" means something different than const char * const func() { return "abc"; } - and it is a good idea to keep the number of reserved words t a minimum in the language, so adding a "constfunc" or something like that to the reserved words was deemed a bad idea. By placing it after the () in the function declaration, it avoids confusion and allows the same word to be used for another purpose.
const does not actually modify the function, but the type of the implicit this pointer. All functions are immutable as far as the C++ type system is concerned (C++ does not provide any language support for self-modifying code).
For that reason it doesn't make sense to compare its position to either the return type or function modifiers.
I have a design question that has been bugging me for a while but I cannot find a good (in a OOP sense) solution for this. The language is C++ and I keep coming back to RTTI - which is often referred to as an indicator for bad design.
Suppose we have a set of different kinds of modules implemented as different classes. Each kind of module is characterized by a defined interface, however the implementation may vary.
Thus my first idea was to create an interface (pure abstract) class for each kind of module (e.g. IModuleFoo, IModuleBar etc.) and the implementations in seperate classes. So far so good.
class IModuleFoo {
public:
virtual void doFoo() = 0;
};
class IModuleBar {
public:
virtual void doBar() = 0;
};
On the other hand we have a set of (application) classes and each of them uses a couple of those modules but only through the interfaces - even the modules themselves might use other modules. However, all of the application classes will share the same pool of modules. My idea was to create a manager class (ModuleManager) for all modules which application classes can query for the module types they need. The available modules (and the concrete implementation) are set up during initialization of the manager and may vary over time (but that is not really part of my question).
Since the number of different module kinds is most probably >10 and may increase over time it does not appear suitable to me to store references (or pointers) to them separately. In addition there might be a couple of functions the manager needs to invoke on all managed modules. Thus I created another interface (IManagedModule) with the benefit that I can now use a container (list, set, whatsoever) of IManagedModules to store them in the manager.
class IManagedModule {
public:
virtual void connect() = 0;
{ ... }
};
The consequence is that a module that shall be managed needs to inherit both from the IManagedModule and from the appropriate interface for its type.
But things turn ugly when I think about the ModuleManager. It can be assumed that there is at most one instance of each module type present at each time. Thus if it was possible to do something like this (where manager is the instance of the ModuleManager), everything would be fine:
IModuleFoo* pFoo = manager.get(IModuleFoo);
But I'm pretty sure that it's not. I also thought about a template based solution like:
IModuleFoo* pFoo = manager.get<IModuleFoo>();
That could work but I have no idea how to find the right module within the manager if all I have is a set of IManagedModules - that is without the use of RTTI, of course.
One approach would be to provide IManagedModule with a virtual getId() method, rely on the implementations to use non-ambigous ids for each kind of module and do the pointer casting on your own. But that's just reinventing the wheel (namely RTTI) and requires a lot of discipline within the implementing classes (providing the right ids etc...) which is not desirable.
Long story short - the question is if there is really no way around some kind of RTTI here and in this case RTTI might even be a valid solution or if there might be a better (cleaner, safer, ...) design which exhibits the same flexibility (e.g. loose coupling between application classes and module classes...)? Did I miss anything?
It sounds like you're looking for something similar to COM's QueryInterface. Now, you don't need to implement COM entirely, but the basic principle stands: You have a base class, with a virtual function, to which you pass an identifier specifying which interface you want. The virtual function then looks to see if it can implement that interface, and if so, passes back a pointer to that interface.
For example:
struct IModuleBase {
// names changed so as not to confuse later programmers with true COM
virtual bool LookupInterface(int InterfaceID, void **interfacePtr) = 0;
// Easy template wrapper
template<typename Interface>
Interface *LookupInterface() {
void *ptr;
if (!LookupInterface(Interface::INTERFACE_ID, &ptr)) return NULL;
return (Interface *)ptr;
}
};
struct IModuleFoo : public IModuleBase {
enum { INTERFACE_ID = 42 };
virtual void foo() = 0;
};
struct SomeModule : public IModuleFoo {
virtual bool LookupInterface(int interface_id, void **pPtr) {
switch (interface_id) {
case IModuleFoo::INTERFACE_ID:
*pPtr = (void*)static_cast<IModuleFoo *>(this);
return true;
default:
return false;
}
}
virtual void foo() { /* ... */ }
};
It's a bit unwieldy, but it's not too bad, and without RTTI you don't have much of a choice besides an approach like this.
I think bdonlan's suggestion is good, but requiring each module type to declare a distinct INTERFACE_ID is a maintenance headache. The distinctness can be accomplished automatically by having each module type declare a static object and using its address as the ID:
struct IModuleFoo : public IModuleBase {
static char distinct_; // Exists only to occupy a unique address
static const void *INTERFACE_ID;
virtual void foo() = 0;
};
// static members need separate out-of-class definitions
char IModuleFoo::distinct_;
const void *IModuleFoo::INTERFACE_ID = &distinct_;
In this case we are using void * as the interface ID type, instead of int or an enumerated type, so the types in some other declarations will need to change.
Also, due to quirks in C++, the INTERFACE_ID values, despite being labelled const, are not "constant enough" to be used for case labels in switch statements (or array size declarations, or a handful of other places), so you would need to change the switch statement to an if. As described in section 5.19 of the standard, a case label requires an integral constant-expression, which roughly speaking is something the compiler can determine just from looking at the current translation unit; while INTERFACE_ID is a mere constant-expression, whose value cannot be determined until link time.
I understand that one benefit of having static member functions is not having to initialize a class to use them. It seems to me that another advantage of them might be not having direct access to the class's not-static stuff.
For example a common practice is if you know that a function will have arguments that are not to be changed, to simply mark these constant. e.g.:
bool My_Class::do_stuff(const int not_to_be_changed_1,
std::vector<int> const * const not_to_be_changed_2)
{
//I can't change my int var, my vector pointer, or the ints inside it.
}
So is it valid to use static member functions to limit access. For example, lets say you have a function
void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
Well here we're not going to be accessing any member variables of the class. So if I changed the function to:
static void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
I'd now get an error, if I inadvertently tried to access one of my private var, etc. (unless I pass myself an instance of my class, which would be purposeful ^_^ !)
Is this a valid technique, similar to proactively making args that should not be changed constants?
What downsides might it have in terms of efficiency or use?
My chief reason for asking is that most of the "static" tutorials I read made no mention of using it in this way, so I was wondering if there was a good reason why not to, considering it seems like a useful tool.
Edit 1: A further logical justification of this use:
I have a function print_error,as outlined above. I could use a namespace:
namespace MY_SPACE {
static void print_error(...) {
...
}
class My_Class {
....
void a(void)
}
}
But this is a pain, because I now have to lengthen ALL of my var declarations, i.e.
MY_SPACE::My_Class class_1;
all to remove a function from my class, that essentially is a member of my class.
Of course there's multiple levels of access control for functions:
//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}
//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
Sure this is a bit atypical, but to lessening degrees so are using const functions and const variables. I've seen lots of examples where people could have used a const function, but didn't. Yet some people think its a good idea. I know a lot of beginning c++ programmers who wouldn't understand the implications of a const function or a static one. Likewise a lot would understand both.
So why are some people so adamantly against using this as an access control mechanism if the language/spec provides for it to be used as such, just as it does with const functions, etc.?
Any member function should have access to the other members of the object. Why are you trying to protect yourself from yourself?
Static members are generally used sparingly, factory methods for example. You'll be creating a situation that makes the next person to work with your code go "WTF???"
Don't do this. Using static as an access-control mechanism is a barbaric abomination.
One reason not to do this is because it's odd. Maintenance programmers will have a hard time understanding your code because it's so odd. Maintainable code is good code. Everybody gets const methods. Nobody gets static-as-const. The best documentation for your code is the code itself. Self-documenting code is a goal you should aspire to. Not so that you don't have to write comments, but so that they won't have to read them. Because you know they're not going to anyway.
Another reason not to do this is because you never know what the future will bring. Your print_error method above does not need to access the class' state -- now. But I can see how it one day might need to. Suppose your class is a wrapper around a UDP socket. Sometime in the middle of the session, the other end slams the door. You want to know why. The last messages you sent or received might hold a clue. Shouldn't you dump it? You need state for that.
A false reason to do this is because it provides member access control. Yes it does this, but there are already mechanisms for this. Suppose you're writing a function that you want to be sure doesn't change the state of the object. For instance, print_error shouldn't change any of the object's state. So make the method const:
class MyClass
{
public:
void print_error(const unsigned int error_no) const;
};
...
void MyClass::print_error(const unsigned int error_no) const
{
// do stuff
}
print_error is a const method, meaning effectively that the this pointer is const. You can't change any non-mutable members, and you can't call any non-const methods. Isn't this really what you want?
Static member functions should be used when they are relevant to the class but do not operate on an instance of the class.
Examples include a class of utility methods, all of which are static because you never need an actual instance of the utility class itself.
Another example is a class that uses static helper functions, and those functions are useful enough for other functions outside the class.
It is certainly fair to say that global scope functions, static member functions, and friend functions aren't quite orthogonal to one another. To a certain extent, this is largely because they are intended to have somewhat different semantic meaning to the programmer, even though they produce similar output.
In particular, the only difference between a static member method and a friend function is that the namespaces are different, the static member has a namespace of ::className::methodName and the friend function is just ::friendFunctionName. They both operate in the same way.
Well, actually there is one other difference, static methods can be accessed via pointer indirection, which can be useful in the case of polymorphic classes.
So the question is, does the function belong as "part" of the class? if so, use a static method. if not, put the method in the global scope, and make it a friend if it might need access to the private member variables (or don't if it doesn't)