How To Initialize a Variable to Previously Allocated Memory? - c++

I'm using C++, and am creating a ex_stage class (a SystemC module, if it makes any difference). In the header file for the class, I define:
public:
ReorderBuffer ROB;
Where ReorderBuffer is another class I have also defined, which has its own constructor. I have defined ROB as a global variable for the ex_stage class so that it can be accessed from multiple functions within ex_stage.
However, I cannot initialize ROB until runtime as it depends on user-supplied values for some of its functionality. So, even though I define ROB as a global variable, I cannot initialize it where it is defined.
Normally, I would do something like this:
ReorderBuffer ROB(<incoming variables>);
within the constructor of ex_stage to construct ROB at the same time. However, since I have already defined ROB, I'm not sure if I am able to do that without causing issues.
Will performing an operation like this actually affect ROB in its original scope, or will it create a new ROB with a scope local to the constructor of ex_stage?
P.S. - Sorry if this is hard to understand please let me know if you need more information.

When you want to initialize something global, you have to be careful about "Global initialization fiasco". If i were you, i would use an unnamed namespace to hide a global var pointer and have some global functions (just inside a named namespace) such as InitMyGlobalVar(), GetMyGlobalVar() to initialize and retrieve the pointer.

If you know how to initialize ROB when your ex_stage constructor runs, you might find a member initializer useful.
Member initializers allow class members to be initialized in a specific way, as opposed to just having their default constructors called:
class ex_stage {
public:
ex_stage() : ROB(<stuff>) {} // constructor that takes <stuff> will be called
ReorderBuffer ROB; // default constructor will _not_ be called
};

Related

Doing necessary work before member initialization in constructor

I've got a design question concerning classes and their constructors in C++. I'm coming from several years of Java experience. In Java, I would do things like this: I've got a class to manage an SQLite DB as a storage backend. In the constructor of this class, I would hand over the path to the applications data directory as a parameter. Then, I would look for the database file, instatiate a connection, and for example load the most current entry of a table for the purpose of caching.
My Problem now is how to do this in C++. My main problem here is that when execution reaches the first statement of the constructor, all class members were already initialized, either implicitly or explicitly.
My question now is: If I had some computations to do on the constructor parameters before using them to initialize the class members, how would I do that in C++?
I've already found that I can simply use assignment to the members in the constructors, but I've also read you should not do that, because it would mean that the members are first initialized with their default constructors, and then initialized again.
What is the canonical way when you have some computation to do (e.g. loading and parsing a configuration file) before class members can be initialized? I would prefer to simply give a path to the constructor, and then do the loading and parsing an member initialization with the loaded values inside the constructor.
Put the computation part in separate function:
class C {
std::string x;
int y;
C(int xarg, int yarg);
};
std::string computeX(int xarg, int yarg) {
...
return result;
}
C::C(int xarg, int yarg) : x(computeX(xarg, yarg)), y(yarg) {}
As the "initialisation" function you may use a global function, a function defined locally in the source file (e.g. in unnamed namespace), or even invoke a lambda defined in place. You can also use a static member function - also if it is private - or a member function of one of the arguments.

Is there any way to change the scope of a callback without changing the paramaters?

I am using SDL2_mixer library, but I believe that the question should hold for the general case also.
Currently, a function that I would like to use, Mix_HookMusicFinished(void (*music_finished)(void)) has a set callback to the global scope for a C style function. However, I would like to have that callback be set to a member function within my own class void CMusic::musicFinished() without having the need for a function in global scope.
Is there anyway to do this? Something like Mix_HookMusicFinished(musicFinished) would be great, but that directly has an error of argument of type "void (CMusic::*)()" is incompatible with parameter of type "void (*)()"
You need to make a "wrapper" function. However, the problem here is that you also need to be able to find the CMusic object that you want to "finish" - this is really what the crux of
argument of type ... is incompatible with ...
is all about. Since there is no way to pass a parameter to the musicFinished object, you will need some other way of "finding" the CMusic object.
If we assume there is a way to do that, then something like this would work:
class CMusic
{
...
public:
...
static void musicFinishedWrapper();
void musicFinished();
...
};
void CMusic::musicFinishedWrapper()
{
CMusic* music = getTheMusicSomehow(); // No idea how you do this - depends on your code.
music->musicFinished();
}
The reason you have to have a CMusic object is that your musicFinished expects a (hidden) this pointer argument - which is the value in music in my little function.
You could move musicFinished to your CMusic class and declare it as a static class method. static class methods aren't called on an object; they therefore don't have an implicit argument to specify the value of the this pointer, and they therefore can have the same signature as freestanding functions. You additionally can make it private to prevent anything but CMusic from using it.
However, since your musicFinished method currently works as a freestanding function and therefore probably doesn't need access to CMusic's protected or private members, and since your efforts to limit its scope presumably means that you don't want other things to call it, I personally would leave your musicFinished function as freestanding but declare it as static (or move it to an anonymous namespace, if you prefer) within the CMusic source (.cpp or .cc) file. Doing so would restrict its scope to the source file (the "compilation unit"). An advantage over a private, static class method is that it does not need to be exposed at all in a header file, so it is in some sense more private.

Why can I not initialize non-static member outside class declaration?

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.

Strange "type class::method() : stuff " syntax C++

While reading some stuff on the pImpl idiom I found something like this:
MyClass::MyClass() : pimpl_( new MyClassImp() )
First: What does it mean?
Second: What is the syntax?
Sorry for being such a noob.
This defines the constructor for MyClass.
The syntax is that of a constructor definition with an initialization list (I assume there is a set of braces following this that define the body of the constructor).
The member pimpl_ of MyClass is being initialized as a pointer to a new object of type MyClassImp. It's almost the same as the following:
MyClass::MyClass()
{
pimpl_ = new MyClassImp();
}
However, it is preferable to use the initialization list for initializing class members wherever possible; see the C++ FAQ Lite entry linked above.
It's an initialization list.
It allow you to set the values of member and base class constructor before the constructor code is called.
You should use it to initialize the values of your class instance.
In addition to being a constructor with an initialiser list as others have already explained, it's also using the private implementation pattern.
C++ requires the class declaration to include all the public and private members of the class. This can result in you having to expose implementation details that you don't want to, and to making your implementation part of your API/ABI. It can also significantly increase compile times due to additional #includes in the public headers to support the private member variables.
Making a second class with the actual implementation and just exposing the functional API makes this much cleaner, but at the cost of an additional layer of indirection.
C generally handles this by having a pointer to an opaque object which the library creates and destroys for you.

Prevent creation of class whose member functions are all static

All the member variables and member functions in my class ClassA are static.
If a user is trying (by mistake) to create an object of this class, he receives a warning: "ClassA, local variable never referenced", because all the functions are static, so this object is never referenced. So, I want to prevent the user from trying to create an object of this class.
Would it be enough to create a private default (no variables) constructor? Or do I have to also create private copy constructor and private assignment operator (to prevent using the default constructors)? And if I do have to create them too, maybe it would be better just to create some dummy pure virtual function instead, and this will prevent the user from creating an object?
Thank you
Instead of using a class with all static methods, you may be better off making the methods free-standing functions in a separate namespace. The call syntax would be the same:
namespace::function() instead of classname::function()
and you don't need to deal with someone trying to instantiate your class.
Creating a private default constructor should be sufficient. Both of the other default constructs (copy constructor and assignment) rely on having an instance to work correctly. If there is no default constructor then there is no way to create an instance, hence no way to actually get to the copy construction part.
It would likely save you a few headaches though to define all 3 as private and not implemented.
Like others said, a namespace is what you should use. If you want to stay with your class, create a class that has a private constructor, and derive from it, to make your intention obvious:
class NonConstructible {
NonConstructible();
};
class SuperUtils: NonConstructible {
static void foo();
// ...
static std::vector<int> globalIDs;
// ...
};
Ok, now let's look into the namespace which are the one and only way to do this:
namespace SuperUtils {
void foo() {
// ....
}
std::vector<int> globalIDs;
};
You can call that using SuperUtils::foo(); in both cases, but the namespace has the advantage that in a scope you can use the namespace declaration and directive to bring certain or all members into the current scope, so that you can reference them without using SuperUtils:::
void superFunction() {
using namespace SuperUtils;
foo();
}
While generally that should be avoided, it can be helpful when the method is using exclusively much stuff from SuperUtils, which then can improve the readability of the code.
In order to use a copy constructor you have to have an object to copy, so if you've locked down the default constructor you should be safe.
The best way to prevent creation of non-heap objects is to make destructor private. Then there is no way compiler can destruct the object when it goes out of scope and it will complain.
This will not prevent anyone from doing new however.