Suppose I have a class X such that all its non-static members are PODs, and a class Y that has the same members in the same order as X, and is also POD itself. Is it legal to reinterpret_cast an instance of Y to X? If it's not, will it work in practice across platforms?
To give you a bit of background, my class X has itself as static members for convenience (i.e. class X { ... public: static const X& a; static const X& b; }, and I want to remove static initializers without changing the API. My plan was to create global static objects of Y type and reinterpret_cast them to X -- since all members are POD, I don't need constructor to be run.
Assuming the layout of the members are exactly the same and you are not introducing any inheritance you can "safely" reinterpret_cast. I put "safely" in quotes for a reason, doing this seems simply a bad idea, you say you want to
...remove static initializers without changing the API. My plan was to create global static objects...
Why would you do this? Keeping a set of static variables in a class has only one drawback, you have to type the name of the class whenever you use it. Also adding the static keyword to a global variable doesn't behave the same as in a class declaration. static when appended to a global variable means that the compiler will only use it in the scope of the translation unit. This means that you could potentially have multiple globals with the same name in separate files. Again this is only adding to the complexity, though you did not specify why you want to do this exactly, i can safely say that what you are trying to accomplish should be and could be solved in a much more scope-oriented fashion.
Related
I inherited a project from a former colleague, and I found these code snippets (and some similar ones in SO questions: can a c++ class include itself as an member and static member object of a class in the same class)
// Service.h
class Service
{
// ...
public:
static Service sInstance;
void Somememberfunc();
//...
};
// Service.cpp
#include "Service.h"
Service Service::sInstance;
void Service::Somememberfunc()
{
//...
}
// Main.cpp
#include "Service.h"
void Fun()
{
Service &instance = Service::sInstance;
//...
instance.Somememberfunc();
//...
}
However, I did not find any explanation on when to use this pattern. And what are the advantages and disadvantages?
Notice that the member is a static, so it's part of the class, not of instantiated objects. This is important, because otherwise you would be trying to make a recursive member (since the member is part of the object, it also contains the same member and so on...), but this is not the case here.
The best pattern to describe this is: global variable. The static member is initialized before main() and can be accessed from any part of the program by including the header file. This is very convenient while implementing but becomes harder to handle the more complex the program gets and the longer you have to maintain it, so the general idea is to avoid this. Also, because there is no way to control the order of initialization, dependencies between different global variables can cause problems during startup.
Static member is roughly a global variable in the scope of the class.
Static members have also the advantage of visibility access (public/protected/private) to restreint its usage (file scope might be an alternative).
That member might be of type of the class.
Global are "easy" to (mis)use, as they don't require to think about architecture.
BUT (mutable) global are mostly discouraged as harder to reason about.
Acceptable usages IMO are for constants:
as for a matrix class, the null matrix, the diagonal one matrix.
for Temperature class, some specific value (absolute 0 (O Kelvin), temperature of water transformation(0 Celsius, 100 Celsius), ...)
in general NullObject, Default, ...
Singleton pattern. For example, you can use it to store your app configurations. And then you can easily access configurations anywhere(globally) within your app.
This is often used in the singleton design pattern
Visit https://en.wikipedia.org/wiki/Singleton_pattern
Can anyone explain why we can call static member functions without creating instance of an object but we can't in case of non-static functions?
I searched everywhere, I couldn't find an explanation, Can you help?
You've got the logic basically in reverse. It is useful to have functions that belong to a class, even though they do not need to be called on an object of that class. Stroustrup didn't want to add a new keyword for that, so he repurposed the existing keyword static to distinguish such methods from normal methods.
In hindsight, other options could have been chosen. We could have made this an explicit function argument for the normal methods, for instance. But that's about 30 years too late now.
Why?
Because we like encapsulation and modularity which we get when using object orientated patterns.
You can view static class member functions and variables as a way of encapsulating what would otherwise have been global functions and variables - which might collide.
Underneath, there is not a great deal of difference between a plain old C++ file with some functions declared and implemented in it, to a class filled with only static functions. The difference is we can cleanly access a set of functions attached to a parent class.
An example:
Suppose you want to create a new class like MyMediumInteger, and you want developers to determine what the maximum number it can hold is. This information is applicable for every instance of MyMediumInteger, no matter what the state of the private member variables are. Therefore it makes sense to expose this information without forcing the developer to instantiate the class. Your options include defining something global such as #define MYMEDIUMINTEGER_MAX ... which could collide with a define sharing the same name in another module, or create a static function returning the max size, called neatly via
MyMediumInteger::maxSize().
A code example:
/***
* Use a static class member function (or variable)
*/
class MyMediumInteger
{
public:
static unsigned long maxSize() { return pow(2, 32) - 1; };
};
auto maxSize = MyMediumInteger::maxSize();
/**
* Alternative approaches.
* Note: These could all collide with other #defines or symbols declared/implemented in other modules.
* Note: These are both independant sources of information related to a class - wouldn't it be nicer if they could just belong to the class instead?
*/
/***
* Use a #define
*/
#define MYMEDIUMINTEGER_MAX (pow(2, 32) - 1)
auto maxSize = MYMEDIUMINTEGER_MAX;
/**
* Use a global function or variable
*/
static unsigned long getMyMediumIntegerMaxSize()
{
return pow(2, 32) - 1;
}
auto maxSize = getMyMediumIntegerMaxSize();
A word of warning:
Static member variables and functions have some of the pitfalls of global variables - because they persist through instances of classes, calling and assigning to them can cause unexpected side effects (because static member variables get changed for everyone, not just you).
A common pitfall is to add lots of static member functions and variables for management - for example, maintaining a list of all other class instances statically which gets appended to in the constructor of each class. Often this type of code could be refactored into a parent class whose job it is just to manage instances of the child class. The latter approach is far more testable and keeps things modular - for example, someone else could come along and write a different implementation of the management code without appending to or re-writing your child class implementation.
How?
In C++ class member functions are not actually stored in class instances, they are stored separately and called on instances of classes. Therefore, it's not hard to imagine how static functions fit into this - they are declared in the same way as normal class member functions, just with the static keyword to say "I don't need to be given a class instance to be run on". The consequence of this is it can't access class member variables or methods.
Static member functions does not need a "this" pointer, it belongs to the class.
Non-static functions need a "this" pointer to point out in which object it belong to, so you need to creat a object firstly.
Because that's what static means: "I don't want this function to require an object to work on".
That's the feature. That's its definition.
Any other answer would be circular.
Why is it useful? Sometimes we want to be able to "organise" some data or utilities in our classes, perhaps for use by external code or perhaps for use by non-static functions of the same class. In that sense there is some crossover with namespaces.
class ClassObject {
public:
ClassObject();
virtual ~ClassObject();
private:
int x;
};
int ClassObject::x=10;
Why does it fail to compile?
I think that if static members can be initialized this way, then it should also be possible for non-static ones.
Static members are special. They have a memory allocated to them as soon as the class is defined. And no matter how many objects of that class we create all those objects refer to the same piece of memory.
This is not the case with non static members. Unless you create an object of that particular class, the non static members are not allocated any memory and hence trying to instantiate them in the above way leads to compiler error.
I'm guessing you mean declaring the value used to initialise x for any new ClassObject, i.e. you mean that as equivalent to
ClassObject() : x(10) { }
The problem with your syntax is that the compiler needs to generate code to do that initialisation in every ClassObject constructor; i.e. it can only work if the int ClassObject::x = 10; initialisation is available in the compilation unit that defines all constructors, and any compilation units that generate one implicitly. And the only way to guarantee that is if the value is set inside the class definition, not outside it as you have. (However this is now possible in C++11 - see the link in tacp's comment.)
If we did want to make your syntax work, then we'd need to store the declared value as a hidden static somewhere in a way that any constructors would pick it up and know to use it as the initial value for x. However this static may or may not exist, and the only point we can know that for a constructor in a different compilation unit is at link time. Hence we either generate extra, redundant code to initialise x from this hidden static if it exists (or redundant data) or we mandate link-time-code-generation to solve this, which puts a large burden on the compiler developer. It is possible, yes, but it's simpler all around if this isn't allowed.
I have been reading through other questions on here and there is something that has me confused and hopefully it can be explained. I am sure there it is a simple thing but it is alluding me.
So in C++ we have private variables that are only viewable within the class:
class MyClass
{
private:
int i;
};
But we can also have unnamed namespaces:
namespace
{
int i;
}
Both appear to be private to the class but in the 2nd case you cannot see they exist from the header file. From reading other questions it seems that functions are different as you can't pass class objects to them? But I am not sure what the difference is here for variables.
Is there a disadvantage to the 2nd way that means you should still use private variables?
They aren't the same.
Integer i in the anonymous namespace will be shared by all instances of MyClass.
The private integer i in MyClass will be unique for each instantiation of the class.
The equivalent using private would be to make i static:
//.h
class MyClass
{
private:
static int i;
};
And instantiate the one single shared i like this:
//.cpp
int MyClass::i = 0;
Both appear to be private to the class ...
No, only the first is private to the class. It's a non-static member variable; one is instantiated in every object of the class type.
The second is not in a class at all; it has static storage duration, so one is instantiated for the whole program. Anything that accesses it is accessing the same variable as anything else that accesses it. Being in an unnamed namespace, it's only accessible within the translation unit (i.e. the source file) that defines it; but it's accessible to any code there, not just a particular class.
Is there a disadvantage to the 2nd way that means you should still use private variables?
If you want a copy of the variable in each class object, then you need it to be a non-static member.
If you want to share it between all objects, then it's up to you whether to make it a static member, or put it in a namespace inside the class's implementation file. I often do the latter to simplify the class definition. Disadvantages are that access isn't restricted just to the class but to anything else in that file, and you can't access it from any code that you might want to put in the header.
Namespaces are unrelated to objects/classes. In particular, if you have two objects, each has its own copy of a private variable.
They are quite different concepts. The private data member is visible only to a class, and in the non-static case, each class instance owns one of these. The anonymous namespace allows you to make code available only to other code in the same file. So in the case of the single int variable, all code defined in the same place as the anonymous namespace would see the same, single variable.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between struct and class in C++
class and struct in c++
It looks like that struct can has constructor and destructor and members, and looks very simple, so can we use struct instead class, if not, when shall we use struct with functions when shall we use class ?
https://github.com/developmentseed/node-sqlite3/blob/master/src/database.h#L32
struct Baton {
uv_work_t request;
Database* db;
Persistent<Function> callback;
int status;
std::string message;
Baton(Database* db_, Handle<Function> cb_) :
db(db_), status(SQLITE_OK) {
db->Ref();
uv_ref(uv_default_loop());
request.data = this;
callback = Persistent<Function>::New(cb_);
}
virtual ~Baton() {
db->Unref();
uv_unref(uv_default_loop());
callback.Dispose();
}
};
struct OpenBaton : Baton {
std::string filename;
int mode;
OpenBaton(Database* db_, Handle<Function> cb_, const char* filename_, int mode_) :
Baton(db_, cb_), filename(filename_), mode(mode_) {}
};
There's absolutely no technical reason to prefer one over the other, but I've noticed a certain convention regarding the use of class or struct.
If your datatype is something that is meant to be used by other parts of your program (ie. it's part of the 'interface'), then usually people make it a class to indicate its importance. If the datatype is used only in the implementation of a function or a class and it is not visible outside of a certain scope, then make it a struct.
These are some very rought guidelines, but no one will complain if you don't follow them.
Edit: In C++ there's no real difference between the two, but other newer languages that are inspired by C++ have actually made struct and class different. In C# and in D, for example, class and struct are both used to define datatypes, but they are not the same: struct is implemented such that it should be used for 'small' types.
The only difference is the default access-level (private for a class, public for a struct). Other than that, they are completely interchangeable. You should decide which one you like better, and use that all the time (consistency makes your code more readable).
when shall we use struct with functions when shall we use class ?
It is completely your choice.
There is nothing that one can do with classes and not with structures in C++.
Only difference between structure and class are:
access specifier defaults to private for class and public for struct
inheritance defaults to private for class and public for struct
So just use the one of your choice and stick to using it consistently, do not mix classes and structures.
While as stated by other struct & class does not have any difference besides default access level. However, it's common practice to use structs mostly for data aggregation, as that is what structs are reduced to in C. For example user defined PODs are almost always created as structs in my experience.
The only difference between class and struct is the default accessibility to its members and base classes. For struct, it is public and for class, it is private.
As others have said, the main difference is the default access level of member data and functions, namely private for class and public for structs. The same goes for default inheritance access levels: private for classes and public for structs.
As for when to use which, that is a matter of what is normal for the company to do. In my experience, most companies, and indeed individuals, use structs to hold packets of pure data and classes for storing a collection of functions that operate on its own data and/or structs.
This method is a throwback to C programming where structs can only store data and not functions and so most people like to stick to this definition in C++ too.
Note that it is common to use structs for functors, which would seem to break consistency through the code of structs not containing functions, but since functors usually only overload the () operator we retain some form of consistency anyway. Plus, it saves us having to type public for one function and/or inherited structures... Oh the typing we allow ourselves to avoid ;)
A class is a reference type. When an object of the class is created, the variable to which the object is assigned holds only a reference to that memory. When the object reference is assigned to a new variable, the new variable refers to the original object. Changes made through one variable are reflected in the other variable because they both refer to the same data.
A struct is a value type. When a struct is created, the variable to which the struct is assigned holds the struct's actual data. When the struct is assigned to a new variable, it is copied. The new variable and the original variable therefore contain two separate copies of the same data. Changes made to one copy do not affect the other copy.
In general, classes are used to model more complex behavior, or data that is intended to be modified after a class object is created. Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created.