How am I supposed to initialize this? [duplicate] - c++

This question already has answers here:
this pointer to base class constructor?
(6 answers)
Closed 8 years ago.
I have an object in my class that only has one constructor, and this constructor takes a pointer to an interface implemented by my class. So I want to put it on the initializer list:
: thatObject(this)
But that gives me a warning and I can understand why giving a pointer to an unconstructed class is not a good idea. So the question is, what do I do? Should I do:
: thatObject(NULL)
{
thatObject = TheClass(this);
}
What is the proper way of dealing with this?
Thanks

If thatObject is guaranteed to never dereference the given pointer until after it's constructor is complete, then ignore or suppress the warning. If you don't feel safe guaranteeing that it will never in the future dereference the pointer, than go with the second option.
In MSVC the code to supress a warning is:
#pragma warning(supress:4355)
: thatObject(this)
GCC is more complicated: (and untested, I don't have GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winit-self"
: thatObject(this)
#pragma GCC diagnostic pop

In general, it's not a good idea to have a pointer to child in the father class. If you need to use that pointer to obtain some information or do something, write a virtual function in father, implement in child and call that.
If you really really have to do that, the method you suggested yourself works fine:
: thatObject(NULL)
{
thatObject = TheClass(this);
}

Related

Why does -Werror=unused-variable not detect some unused variables? [duplicate]

This question already has answers here:
A variable not detected as not used
(3 answers)
Closed 6 years ago.
#include <vector>
class Object
{
};
int main()
{
Object myObject;
std::vector<int> myVector;
}
Compiler emits:
warning: unused variable 'myObject' [-Wunused-variable]
No warning for myVector. Why? Is there any way to enable this?
Whether declaring (and thus initialising and at some point destructung) an arbitrary object has visible side effects cannot be determined in general. The constructor may be calling functions whose definition is not known to the compiler or it may depend on external state or any other aspect which makes the problem undecidable.
In your first case, the constructor is trivial (not even declared), same for the destructor. As Object does not have members, it is clear and easily detectable that Object foo does in fact nothing.
std::vector has a non-trivial constructor which may be allocating memory (external state + function whose definition may not be known (new ...)) together with a non-trivial destructor (also external state + function whose definition may not be known (delete ...)). Reasoning about whether it is safe to remove the declaration (thus emitting a warning hinting that you maybe should) is not possible in this case, thus the compiler has to leave the declaration in the code (and must assume that the declaration is there for a reason).
A prime example is std::lock_guard which is used to lock a mutex when it is constructed and unlock it automatically when it is destructed. The mutex is thus held as long as the object is in scope; generally you would not access the std::lock_guard object at all though—nevertheless it is useful to have it declared. This is the RAII principle at work.
Emitting a warning in such cases would be a nuisance, leading to people turning off the warning, which in turn would render the warning useless. (The compiler may even be designed in such a way that it only emits the warning if it has removed the declaration during optimisation, which is also the reason why some warnings only show up if certain optimisations are enabled.)
This warning is generated only for trivial types. Compiler is not able to find whether construct will call any external function. If you add a constructor to your Object class then compiler will also issue a warning. Gcc allows to tag types which should generate this warning, you can do this using __attribute__((warn_unused)) :
http://coliru.stacked-crooked.com/a/0130c8ef29c121a1
example:
class __attribute__((warn_unused)) Object
{
public:
Object(){}
void use() {}
};
int main()
{
Object myObject; // will give : warning: unused variable 'myObject' [-Wunused-variable]
//myObject.use(); // uncomment to hide this warning
}
[edit]
from gcc attributes page: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html :
warn_unused For C++ types with non-trivial constructors and/or
destructors it is impossible for the compiler to determine whether a
variable of this type is truly unused if it is not referenced. This
type attribute informs the compiler that variables of this type should
be warned about if they appear to be unused, just like variables of
fundamental types. This attribute is appropriate for types which just
represent a value, such as std::string; it is not appropriate for
types which control a resource, such as std::lock_guard.
This attribute is also accepted in C, but it is unnecessary because C
does not have constructors or destructors.
As well as the answers above, also check your compiler documentation. Some compilers can be set so that they do not show the same warning multiple times. If you comment out the declaration of "myObject", you may then get the same warning for "myVector". With "mObject" producing that warning first, you wouldn't get a warning for "myVector".
Compiler behaviour in the case of warnings is very compiler-specific, so don't assume that all compilers work the same. :)

What is the difference between setting the copy constructor to private and =delete? [duplicate]

This question already has answers here:
delete modifier vs declaring function as private
(4 answers)
Closed 3 years ago.
I have seen a lot of books recommend using =delete, is this just clear what it means? (making the program more readable) rather than saying that it is a bad thing to set the copy constructor to private?
Thinks your answers
class A {
A(const A&);
// some functions and variable
public:
// or you can A(const A&)=delete;
// do something
};
This is a relatively new functionality (added in the 2011 revision of C++) whose main motivation surely was readability and clarity of intent. However, the difference is more than just cosmetic.
Remember that with a constructor declared in the class, nothing prevents some other translation unit from actually providing the definition. It is quite usual to just list a class' member functions in a header file and implement them in a separate .cpp. If someone uses the copy constructor from inside the class, the compiler will complain that the definition is missing ("undefined reference to..."). If a naive programmer somehow reaches the conclusion that you forgot to implement it because you never needed it, they can go ahead and do so. Suddenly your class is copyable, even though only from within its own member functions (and friends). The =delete constructor prevents this, and the compiler errors are nicer (usually along the lines of "the object can't be copied because the copy constructor was declared as deleted" rather than "undefined reference to ..." or "A::A is private within this context").

Why the compiler does not issue a warning when an object std::vector is declared but never used? [duplicate]

This question already has answers here:
A variable not detected as not used
(3 answers)
Closed 6 years ago.
#include <vector>
class Object
{
};
int main()
{
Object myObject;
std::vector<int> myVector;
}
Compiler emits:
warning: unused variable 'myObject' [-Wunused-variable]
No warning for myVector. Why? Is there any way to enable this?
Whether declaring (and thus initialising and at some point destructung) an arbitrary object has visible side effects cannot be determined in general. The constructor may be calling functions whose definition is not known to the compiler or it may depend on external state or any other aspect which makes the problem undecidable.
In your first case, the constructor is trivial (not even declared), same for the destructor. As Object does not have members, it is clear and easily detectable that Object foo does in fact nothing.
std::vector has a non-trivial constructor which may be allocating memory (external state + function whose definition may not be known (new ...)) together with a non-trivial destructor (also external state + function whose definition may not be known (delete ...)). Reasoning about whether it is safe to remove the declaration (thus emitting a warning hinting that you maybe should) is not possible in this case, thus the compiler has to leave the declaration in the code (and must assume that the declaration is there for a reason).
A prime example is std::lock_guard which is used to lock a mutex when it is constructed and unlock it automatically when it is destructed. The mutex is thus held as long as the object is in scope; generally you would not access the std::lock_guard object at all though—nevertheless it is useful to have it declared. This is the RAII principle at work.
Emitting a warning in such cases would be a nuisance, leading to people turning off the warning, which in turn would render the warning useless. (The compiler may even be designed in such a way that it only emits the warning if it has removed the declaration during optimisation, which is also the reason why some warnings only show up if certain optimisations are enabled.)
This warning is generated only for trivial types. Compiler is not able to find whether construct will call any external function. If you add a constructor to your Object class then compiler will also issue a warning. Gcc allows to tag types which should generate this warning, you can do this using __attribute__((warn_unused)) :
http://coliru.stacked-crooked.com/a/0130c8ef29c121a1
example:
class __attribute__((warn_unused)) Object
{
public:
Object(){}
void use() {}
};
int main()
{
Object myObject; // will give : warning: unused variable 'myObject' [-Wunused-variable]
//myObject.use(); // uncomment to hide this warning
}
[edit]
from gcc attributes page: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html :
warn_unused For C++ types with non-trivial constructors and/or
destructors it is impossible for the compiler to determine whether a
variable of this type is truly unused if it is not referenced. This
type attribute informs the compiler that variables of this type should
be warned about if they appear to be unused, just like variables of
fundamental types. This attribute is appropriate for types which just
represent a value, such as std::string; it is not appropriate for
types which control a resource, such as std::lock_guard.
This attribute is also accepted in C, but it is unnecessary because C
does not have constructors or destructors.
As well as the answers above, also check your compiler documentation. Some compilers can be set so that they do not show the same warning multiple times. If you comment out the declaration of "myObject", you may then get the same warning for "myVector". With "mObject" producing that warning first, you wouldn't get a warning for "myVector".
Compiler behaviour in the case of warnings is very compiler-specific, so don't assume that all compilers work the same. :)

C++ VS2013: overwriting default constructor not working [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 8 years ago.
I have a weird problem in C++. Probably I am just doing something wrong, but I can't figure out, what. I am using Microsoft VS2013 if that is important.
I created a new class with two constructors:
class CtVolume{
public:
CtVolume();
CtVolume(std::string path);
...
The first one should overwrite the default constructor. This is the one that does not work as I expected. If I do something like:
CtVolume myVolume();
then I think this should call the default constructor that I defined and execute the code I implemented for it. But it doesn't. The code in my Constructor is not executed. What is even more puzzling is that I can't use the myVolume like an object afterwards. If I attempt to call one of the methods implemented in the class:
myVolume.reconstructVolume();
The compiler does not let me compile my code. It says:
Error 5 error C2228: left of '.reconstructVolume' must have class/struct/union
So as it seems, this way I can't create an object.
Now, if I create the object with the keyword 'new' instead, my constructor code is being executed and everything works as expected. Example:
CtVolume* myVolume = new CtVolume();
myVolume->reconstructVolume();
This works fine.
Now another thing: if I use the other constructor I defined, both ways of creating the object work equally good, meaning this example:
CtVolume myVolume("sourcefiles/data/skullPhantom");
myVolume.reconstructVolume();
compiles and works as expected.
Now I tried to find out what type of myVolume is in the different cases, by calling typeid(myVolume).name(). This returns the type class CtVolume __cdecl(void) in the case that I described, where it "doesn't work" and class CtVolume in the "working" case where I used the other constructor.
Now can anybody tell me, what the __cdecl(void) means and what I did wrong?
What also puzzles me is that I think I did that a lot of times before and it always worked for me until now.
Thanks!
The line:
CtVolume myVolume();
is interpreted by the compiler as a function declaration. Take a look at most vexing parse.
Just do:
CtVolume myVolume;
The above code will call the default constructor appropriately.

C++ Question about default constructor [duplicate]

This question already has answers here:
Closed 14 years ago.
What does it mean to call a class like this:
class Example
{
public:
Example(void);
~Example(void);
}
int main(void)
{
Example ex(); // <<<<<< what is it called to call it like this?
return(0);
}
Like it appears that it isn't calling the default constructor in that case. Can someone give a reason why that would be bad?
Thanks for all answers.
Currently you are trying to call the default constructor like so.
Example ex();
This is not actually calling the default constructor. Instead you are defining a function prototype with return type Example and taking no parameters. In order to call the default constructor, omit the ()'s
Example ex;
This declares a function prototype for a function named ex, returning an Example! You are not declaring and initializing a variable here.
Does it even compile? Anyway, see this related topic.
As has been noted Example ex(); declares a function prototype. Not what anyone would expect. This C++ wart will be fixed by the new C++0x standard. In the future the preferred syntax will be Example ex{};. The new uniform construction has many other nice features, see more here.