Imagine I have a C++ class called MyClass.
Imagine that I have no access to the source code of MyClass ... it is contained in a library and I am supplied only the library and the header file for MyClass.
Imagine that the class itself requires environment pre-configuration ... for example ... before the constructor of the class can be called, I need to do some setup. The class is normally meant to be used as follows:
void func() {
doGlobalSetup();
MyClass myInstance(1,2,3);
myInstance.doSomething();
...
}
Now I have the situation where we need to create a global instance of the class such as:
MyClass myInstance(1,2,3);
int main(int argc, char *argv[]) {
doGlobalSetup();
myInstance.doSomething();
}
The problem is that in this story, the instance of MyClass is created before the call to doGlobalSetup(). It is instantiated before main() is called. What I want to do is either defer the creation of myInstance() till later or be able to run doGlobalSetup() somehow before the instantiation of the class.
This is a simplification of the actual story ... so let us assume:
I can't change the internals of MyClass.
There must be an instance variable called myInstance of type MyClass (I can't change the logic to MyClass *pMyInstance).
Many thanks for reading.
Since you've constrained the problem such that new cannot be used, you should be able to create the object as always and copy it to the global instance. For example:
MyClass createMyClass()
{
doGlobalSetup();
return MyClass(1, 2, 3);
}
MyClass myInstance = createMyClass();
int main()
{
myInstance.doSomething();
return 0;
}
Does it suit your needs?
namespace
{
int doStaticGlobalSetup()
{
doGlobalSetup();
return 0;
}
}
MyClass myInstance(doStaticGlobalSetup() + 1,2,3);
int main() {
myInstance.doSomething();
return 0;
}
If you absolutely have to defer any constructor calls until after global initialization is done, and want to be sure that no static order initialization fiasco happens, there is a way: make myInstance a reference to uninitialized block of memory and create object in it using placement new after global initializaton.
#include <iostream>
#include <type_traits>
struct foo
{
foo() { std::cout << "created\n"; }
void meow() { std::cout << "used\n"; }
~foo() { std::cout << "destroyed\n"; }
};
void doGlobalSetup() { std::cout << "Global setup\n"; }
//Actual implementation
namespace {
typename std::aligned_storage<sizeof(foo), alignof(foo)>::type bar;
}
foo& instance = reinterpret_cast<foo&>(bar);
//Allows automatic creation and destruction
struct initializer
{
initializer()
{
if (!initialized)
new (&instance) foo();
initialized = true;
}
~initializer()
{
if(initialized)
instance.~foo();
initialized = false;
}
private:
static bool initialized;
};
bool initializer::initialized = false;
int main()
{
doGlobalSetup();
initializer _;
instance.meow();
}
Use a static variable inside a function.
MyClass &myInstance() {
doGlobalSetup();
static MyClass myInstance(1,2,3);
return myInstance;
}
void func() {
myInstance().doSomething();
}
You probably already got the answer you wanted. But just to cover the whole spectrum: if, for some reason, you want to make sure that other places in the code don't accidentally construct MyClass independently of your global variable--and before the global setup has been made--you need to solve this with linking.
If you're on Linux, you can LD_PRELOAD a shared-object containing just the symbol for MyClass's constructor. In it, you declare the setup function accordingly, and let the dynamic linker do the job for you. Then, inside the constructor, you call the setup function, and then do a dlsym("...", RTLD_NEXT) to get the pointer to the original constructor, and you call it, passing it the arguments you got. Of course, you maintain and check a static flag for whether setup has already been performed.
Again, this is probably overkill for you, but I'm posting it just in case someone needs (and is able to use) this kind of solution.
P.S. This is what you get when you rely on global state! :)
First, bear in mind that given a library init function like doGlobalSetup there is a distinct nonzero chance the library will just not work if you create a global instance.
Otherwise it's super easy to create an initializer with the comma operator:
bool do_my_setup = (doGlobalSetup(), true);
MyClass myInstance(1,2,3);
Within the GCC compiler environment there is a function attribute capability called constructor. This allows us to flag a function definition with the ability for it to be automatically invoked before main is called and, most importantly before any class constructors are invoked.
Referring back to the original problem definition ... if the doGlobalSetup() function is modified from:
void doGlobalSetup() { ... }
to
__attribute__((constructor)) void doGlobalSetup() { ... }
then its invocation will occur before main is called and also before any static class instance constructors are called. The explicit call to this function would also be removed from main() as its work has been performed implicitly.
Related
I have the following situation. This is the stripped down version of the class. I'm running it in Qt creator and using Qt in the real scenario.
class MyClass
{
public:
MyClass();
static MyClass *instance;
static void myMethod(int a, int b);
int name;
};
MyClass *MyClass::instance = 0;
MyClass::MyClass(){
if (instance)
exit(-1);
instance = this;
}
void MyClass::myMethod(int a, int b){
if(instance->name == a) qDebug() << "hello";
}
int main(int argc, char *argv[])
{
MyClass cls;
cls.myMethod(1,2);
}
I'm trying to debug myMethod by stepping into it with the debugger. When i enter the method, only the a 1 and b 2 are visible in the watch and there is no reference to this or instance.
Update
The answers stated that static methods are not bound to the object which is why there is no this available.
In this implementation, the static method accesses the instance and that's what I'd like to have available in the debugger once i step into myMethod.
How would I make that available/visible?
Static methods are actually called without an object. The call
MyClass cls;
cls.myMethod(1,2)
is equivalent to
MyClass::myMethod(1, 1)
As a consequence myMethod is not receiving any this value.
Such behavior is to be expected, since a static method has no access to this, as it is not bound to an object.
Simple solution from this answer :
You cannot access a non static member inside a static method unless you explicitly make available the object instance inside the member function.(Pass object instance explicitly as argument or use a global instance which can be accessed inside the function)
That means to change the method into this :
static void myMethod(MyClass instance, int a, int b);
The reason is that static methods don't act on any object and there is no this. Actually, it's quite unusual to call static function on an object. This would do the same and is the more usual way to call satic functions:
int main(int argc, char *argv[])
{
MyClass cls;
MyClass::myMethod(1,2); //look Ma, no object!
}
With this it becomes obvious that the cls object is not needed at all in your example code, so you could leave it out entirely. The same applies to the arguments to main, since you don't use them.
I am trying to create two classes whose instances get created and deleted together. One class is a base for the other:
class Interface;
class MyClass
{
friend class Interface;
private:
MyClass() {}
public:
static MyClass *NewInstance();
Interface *ControlPanel;
};
class Interface : public MyClass
{
friend class MyClass;
private:
Interface() {}
public:
void Control1() {cout << "control1" << endl;}
void Control2() {cout << "control2" << endl;}
void Control3() {cout << "control3" << endl;}
};
The two member functions that are supposed to create and delete instances are:
MyClass *MyClass::NewInstance()
{
MyClass *inst = new MyClass;
inst->ControlPanel = new Interface;
return inst;
}
void DeleteMyClassInstance(MyClass *inst)
{
delete inst->ControlPanel;
inst->ControlPanel = 0;
delete inst;
inst = 0;
}
I had success in linking the instance creation process with the use of a function in the base class (NewInstance()) which creates the instances. But the deletion function (DeleteMyClassInstance()) doesn't work (that is, I can still use both inst1 and inst1->ControlPanel after calling the function):
int main()
{
MyClass *inst1 = MyClass::NewInstance();
inst1->ControlPanel->Control1();
DeleteMyClassInstance(inst1);
inst1->ControlPanel->Control1();
return 0;
}
But if I put the deletion code inside the main function, it works perfectly (the inst1->ControlPanel->Control1() statement that comes after the delete statements doesn't work, and that's what I want):
int main()
{
MyClass *inst1 = MyClass::NewInstance();
inst1->ControlPanel->Control1();
delete inst->ControlPanel;
inst->ControlPanel = 0;
delete inst;
inst = 0;
inst1->ControlPanel->Control1();
return 0;
}
My question is: Why does putting the delete statements directly inside the main function work while putting them inside a separate function and using it in main doesn't? Why does the code in my DeleteMyClassInstance() function get ignored by the compiler?
The main difference is that with the code in the main function inst=0 sets the variable in the main function to null. With the code in DeleteMyInstance, the line inst=0 only sets the local variable in DeleteMyInstance to null (uselessly, since it is unused after that point -- enable more warnings and your compiler might mention it). It doesn't affect the completely separate variable of the same name in main.
So, your code
DeleteMyClassInstance(inst1);
inst1->ControlPanel->Control1();
has undefined behavior because you attempt to use an object that has already been deleted. UB means that anything can happen. If it appears to work that is probably because in your implementation the function Control1 still "works" even when called on a null (or otherwise-invalid) pointer, since the function doesn't use this or any data members. But that implementation detail should not be relied on.
Be aware (if you aren't already) that your code shows some bad C++ style. You should not write special functions to delete objects owned by your class, that's what destructors are for. And you shouldn't have to explicitly delete objects in destructors, that's what smart pointers are for. And you shouldn't use dynamic allocation when not needed, that's what automatic variables and data members are for. By all means get this code right once, as a learning exercise what goes on behind the scenes, but that should be with a view to doing it properly as soon as possible.
Change your DeleteMyClassInstance function to.
void DeleteMyClassInstance(MyClass **inst)
{
delete (*inst)->ControlPanel;
(*inst)->ControlPanel = 0;
delete (*inst);
*inst = 0;
}
I would like to have a class T that can generate only 1 instance in the whole program.
Now i know about std::unique_ptr but there are 2 problems:
it's limited to a scope ( but it's not a big issue ... )
it needs to be explicitly used, meaning that it's not part of the class or the type, it's just and handler and a special pointer, but it does not modify the design of my class.
now i would like to have class T designed in a way that not even by mistake the user can declare 2 instances in the same program and i can't rely on the fact that my user will declare an std::unique_ptr for T because i want to solve this by design.
right now i'm only thinking about how to make an implicit use of an unique_ptr in an elegant way, the problem is that i do not have any clue at the moment.
the other way around is to check if this class is handled by an unique_ptr but this check will make me lose an edge in terms of performances.
since having only 1 instance is really important, i see only 2 options in my case: 1) trying to solve this by design 2) throwing errors at compile time with some sort of check/macro.
I know that this looks trivial but with a design approach it's not, at least for me, so please help.
What you're looking for is called the Singleton pattern, and while it is widely considered by many (myself included) to be an anti-pattern, I will nonetheless show you the basic elements needed to build one.
Basically what you need to do is provide three things:
A static method which "gets" the one and only instance
A private constructor, so that nobody can ever instantiate it
(optional) A means by which the one and only instance is created before main starts
Here's the essential code:
class Singleton
{
public:
Singleton& get()
{
static Singleton me_;
return me_;
}
private:
Singleton() {};
};
I leave it to you to discover how to implement #3 above, and why you shouldn't be using a Singleton in the first place -- there are many reasons.
This is typically referred to as a Singleton.
See http://en.wikipedia.org/wiki/Singleton_pattern
The typical trick in C++ is to have a function which returns the singleton instance by reference, and make the constructor private.
Something like:
#include <iostream>
using namespace std;
class Foo
{
private:
Foo() : a(3) { a++; }
static Foo singleton;
int a;
public:
static Foo& getFoo() { return singleton; }
void doStuff() { cout<<"My a is: "<<a<<endl; }
};
Foo Foo::singleton;
int main(int argc, char** argv)
{
Foo::getFoo().doStuff();
Foo &foo = Foo::getFoo();
foo.doStuff();
//uncomment below to cause compile error
//Foo foo2;
}
Note that in real code you'll split this up into a header and a cpp file. In that case the
Foo Foo::singleton;
part must go in the cpp file.
You could have at least
static int count;
assert(count == 0);
count++;
in the constructor(s) of the singleton class. This don't ensure at compile time that your class is singleton, but at least it checks that at runtime.
And you could also make the constructor private, and have a static member function returning (once) a pointer to your instance, perhaps something like
class Singleton {
private:
Singleton() {
static int count;
assert(count == 0);
count++;
};
Singleton(Singleton&) = delete;
public:
static Singleton* the_instance() {
static Singleton* it;
if (!it) it = new Singleton();
return it;
}
};
If I have two static variables in different compilation units, then their initialization order is not defined. This lesson is well learned.
The question I have: are all the static variables already allocated, when the first one is being initialized. In other words:
static A global_a; // in compilation unit 1
static B global_b; // in compilation unit 2
struct A {
A() { b_ptr = &global_b; }
B *b_ptr;
void f() { b_ptr->do_something(); }
}
int main() {
global_a.f();
}
Will b_ptr point to a valid piece of memory, where B is allocated and initialized at the time of the execution of the main function? On all the platforms?
Longer story:
The compilation unit 1 is Qt library.
The other one is my application. I have couple QObject derived classes, that I need to be able to instantiate by the class name string. For this I came up with a templated factory class:
class AbstractFactory {
public:
virtual QObject *create() = 0;
static QMap<const QMetaObject *, AbstractFactory *> m_Map;
}
QMap<const QMetaObject *, AbstractFactory *> AbstractFactory::m_Map; //in .cpp
template <class T>
class ConcreteFactory: public AbstractFactory {
public:
ConcreteFactory() { AbstractFactory::m_Map[&T::staticMetaObject] = this; }
QObject *create() { return new T(); }
}
#define FACTORY(TYPE) static ConcreteFactory < TYPE > m_Factory;
Then I add this macro on every QObject subclass definition:
class Subclass : public QObject {
Q_OBJECT;
FACTORY(Subclass);
}
Finally I can instantiate a class by the type name:
QObject *create(const QString &type) {
foreach (const QMetaObect *meta, AbstractFactory::m_Map.keys() {
if (meta->className() == type) {
return AbstractFactory::m_Map[meta]->create();
}
}
return 0;
}
So the class gets a static QMetaObject instance: Subclass::staticMetaObject from the Qt library - it is auto-generated in Q_OBJECT macro I think. And then the FACTORY macro creates a static ConcreteFactory< Subclass > instance. ConcreteFactory in its constructor tries to reference of Subclass::staticMetaObject.
And I was pretty happy with this implementation on linux (gcc), until I compiled it with Visual Studio 2008. For some reason AbstractFactory::m_Map was empty on the runtime, and the debugger would not break at the factory constructor.
So this is where the smell of static vars referencing other static vars is coming from.
How can I optimize this code to avoid all these traps?
Yes, the standard allows this.
There are a number of paragraphs in section [basic.life] which start out
Before the lifetime of an object has
started but after the storage which
the object will occupy has been
allocated or, after the lifetime of an
object has ended and before the
storage which the object occupied is
reused or released, any pointer that
refers to the storage location where
the object will be or was located may
be used but only in limited ways.
and there is a footnote which indicates that this specifically applies to your situation
For example, before the construction of a global object of non-POD class type
Short Answer: Its should work as you have coded it. See Ben Voigt Answer
Long Answer:
Do something like this:
Rather than let the compiler decide when globals are created, create them via static methods (with static function variables). This means that they will be deterministically created on first use (and destroyed in the reverse order of creation).
Even if one global uses another during its construction using this method gurantees that they will be created in the order required and thus be available for usage by the other (watch out for loops).
struct A
{
// Rather than an explicit global use
// a static method thus creation of the value is on first use
// and not at all if you don't want it.
static A& getGlobalA()
{
static A instance; // created on first use (destroyed on application exit)
// ^^^^^^ Note the use of static here.
return instance; // return a reference.
}
private:
A()
:b_ref(B::getGlobalB()) // Do the same for B
{} // If B has not been created it will be
// created by this call, thus guaranteeing
// it is available for use by this object
}
B& b_ref;
public:
void f() { b_ref.do_something(); }
};
int main() {
a::getGlobalA().f();
}
Though a word of warning.
Globals are an indication of bad design.
Globals that depend on other globals is another code smell (especially during construction/destruction).
Yes. All are located in .data section, that is allocated at once (and it's not heap).
Putting it another way: if you are able to take its address, then it's OK, because it surely won't change.
If B has a constructor, like A has, then the order that they are called is undefined. So your code won't work unless you are lucky. But if B doesn't require any code to initialise it, then your code will work. It's not implementation-defined.
Ah, but the idea that static variables are "not initialised" is quite wrong. They're always initialised, just not necessarily with your initialiser. In particular, all static variables are created with value zero before any other initialisation. For class objects, the members are zero. Therefore global_a.b_ptr above will always be a valid pointer, initially NULL and later &global_b. The effect of this is that use of non-pointers is unspecified, not undefined, in particular this code is well defined (in C):
// unit 1
int a = b + 1;
// unit 2
int b = a + 1;
main ... printf("%d\n", a + b); // 3 for sure
The zero initialisation guarantee is used with this pattern:
int get_x() {
static int init;
static int x;
if(init) return x;
else { x = some_calc(); init = 1; return x; }
}
which assures either a non-return due to infinite recursion, or, correctly initialised value.
In C++, is it possible to call a function of an instance before the constructor of that instance completes?
e.g. if A's constructor instantiates B and B's constructor calls one of A's functions.
Yes, that's possible. However, you are responsible that the function invoked won't try to access any sub-objects which didn't have their constructor called. Usually this is quite error-prone, which is why it should be avoided.
This is very possible
class A;
class B {
public:
B(A* pValue);
};
class A {
public:
A() {
B value(this);
}
void SomeMethod() {}
};
B::B(A* pValue) {
pValue->SomeMethod();
}
It's possible and sometimes practically necessary (although it amplifies the ability to level a city block inadvertently). For example, in C++98, instead of defining an artificial base class for common initialization, in C++98 one often see that done by an init function called from each constructor. I'm not talking about two-phase construction, which is just Evil, but about factoring out common initialization.
C++0x provides constructor forwarding which will help to alleviate the problem.
For the in-practice it is Dangerous, one has to be extra careful about what's initialized and not. And for the purely formal there is some unnecessarily vague wording in the standard which can be construed as if the object doesn't really exist until a constructor has completed successfully. However, since that interpretation would make it UB to use e.g. an init function to factor out common initialization, which is a common practice, it can just be disregarded.
why would you wanna do that? No, It can not be done as you need to have an object as one of its parameter(s). C++ member function implementation and C function are different things.
c++ code
class foo
{
int data;
void DoSomething()
{
data++;
}
};
int main()
{
foo a; //an object
a.data = 0; //set the data member to 0
a.DoSomething(); //the object is doing something with itself and is using 'data'
}
Here is a simple way how to do it C.
typedef void (*pDoSomething) ();
typedef struct __foo
{
int data;
pDoSomething ds; //<--pointer to DoSomething function
}foo;
void DoSomething(foo* this)
{
this->data++; //<-- C++ compiler won't compile this as C++ compiler uses 'this' as one of its keywords.
}
int main()
{
foo a;
a.ds = DoSomething; // you have to set the function.
a.data = 0;
a.ds(&a); //this is the same as C++ a.DoSomething code above.
}
Finally, the answer to your question is the code below.
void DoSomething(foo* this);
int main()
{
DoSomething( ?? ); //WHAT!?? We need to pass something here.
}
See, you need an object to pass to it. The answer is no.