Passing this as argument to members in C++ - c++

I want to pass this as argument to member variable like this:
template<class T>
struct fun
{
fun(T* pointer) : memberPointer(pointer)
{
}
T* memberPointer;
};
struct gun
{
gun() : member(this)
{
}
fun<gun> member;
};
In Visual Studio I have next warning: warning C4355: 'this' : used in base member initializer list
Can you please explain why is it wrong to do this? I just store the pointer in member constructor to use it later to call some gun functions from fun.

The potential problem is that this points to an object that has not been fully constructed. So for example if you had this:
template<class T>
struct fun
{
fun(T* pointer) : memberPointer(pointer)
{
memberPointer->callMethod(); //this is 2nd to execute
}
T* memberPointer;
};
struct gun
{
gun() : member(this) //this is 1st to execute
{
ptr = new char(); // this is 4rd to execute unless earlier UB prevents execution
}
void callMethod()
{
printf("%s", ptr); //this is 3rd to execute, you get UB here
}
fun<gun> member;
char* ptr;
};
you would run into undefined behavior because you would pass a pointer to a not fully constructed object where only a pointer to a fully constructed object should be passed. I intentionally crafted some crappy code with UB to be more convincing, in real life you won't necessarily have UB as a problem, sometimes all the objects will be in valid states so you will get some really subtle initialization order bugs.
That's not your case. Your case is fine - you don't care that the object is not yet fully constructed. However you should be careful when changing your code so that you don't get into scenario as above.

It's only a warning. If you were to deference this inside the fun constructor then you would be accessing an uninitialised object. But you aren't, you are only storing the pointer, so you can ignore the warning. If you want to turn off the warning then add this at the top of your code
#pragma warning (disable: 4355)

It is not completely wrong, but as you pass the pointer, your gun object might not be fully constructed yet. Hence, it might happen that you call methods in the base class that rely on the complete construction of your object.

What you want is to achieve static polymorphism, which is best handled through the curiously recurring template pattern (CRTP). In your case, you're almost there:
template<class Base>
struct fun : public Base
{
void foo()
{
// call gun function
Base::bar();
}
};
struct gun : public fun<gun>
{
void bar()
{
/*...*/
}
};

Related

C++ Smart Pointer Lost in std::make_unique

I am in the process of converting some legacy code to take advantage of smart pointers in C++. However, I ran into a runtime issue that I'm struggling to figure out. I have code such as the following:
struct foo {
int field;
};
class SomeClass {
private:
std::unique_ptr<foo> m_Foo;
int m_Field;
public:
SomeClass(std::unique_ptr<int> ctorArg)
: m_Field(ctorArg->field), m_Foo(std::move(ctorArg)) {
}
};
std::unique_ptr<foo> fooPtr{ new foo() };
auto const classInstance{ std::make_unique<SomeClass>(std::move(fooPtr)) };
If I put a breakpoint prior to calling the SomeClass constructor, I can verify that fooPtr is not null. However, once I am within the SomeClass constructor, the application is crashing when trying to initialize m_Field, since ctorArg is null (empty). Is this expected? If I change the constructor signature to take std::unique_ptr<int> &&, I see the same issue. Can someone please explain what the issue is with this code, and how to go about fixing it?
The order of member-initializer-list is irrelevant, the members will be initialized in the order of their declaration.
So, first m_Foo(std::move(ctorArg)) will zero out ctorArg then m_Field(ctorArg->field) will attempt to derefence an empty ctorArg.
Change your code to:
class SomeClass {
private:
std::unique_ptr<foo> m_Foo;
int m_Field;
public:
SomeClass(std::unique_ptr<int> ctorArg)
: m_Foo(std::move(ctorArg)), m_Field(m_Foo->field) {
}
};
That is, always mention initializers in the order the fields are declared, and don't use input arguments which have been moved-out from.

CRTP copy method warns of potential memory leak

I have an object hierarchy and need to be able to clone objects from the base class. I've followed the typical CRTP pattern, except that I also want to be able to return the child class if copy is called on a child directly. To do that, I've followed the suggestion here: https://stackoverflow.com/a/30252692/1180785
It seems to work fine, but Clang warns me that I have a potential memory leak. I've reduced the code down to this MCVE:
template <typename T>
class CRTP {
protected:
virtual CRTP<T> *internal_copy(void) const {
return new T(static_cast<const T&>(*this));
}
public:
T *copy(void) const {
return static_cast<T*>(internal_copy());
}
virtual ~CRTP(void) = default;
};
class Impl : public CRTP<Impl> {
};
int main(void) {
Impl a;
Impl *b = a.copy();
delete b;
}
As far as I can tell, there's no possible memory leak there, but running Clang through XCode shows this:
Is there a memory leak here? If not, what's causing the false positive and how can I work around it? (I'd rather not turn off static analysis)
I have found a workaround which makes the analyser happy while still allowing the use of this pattern. Simply reverse the link between copy and internal_copy:
template <typename T>
class CRTP : public Base {
protected:
virtual CRTP<T> *internal_copy(void) const {
return copy();
}
public:
T *copy(void) const {
return new T(static_cast<const T&>(*this));
}
};
This still works in the context of the original suggestion here, because when resolving copy inside CRTP, it will prefer CRTP's override (even though it isn't a virtual method), so there is no infinite loop.
As for why the analyser is happy with this order but unhappy with the original order, I have no idea.
I think the analyzer is getting confused by the static_cast in your copy method. If you simply change it to dynamic_cast, it ceases to flag the line as a memory leak. This leads me to believe that it thinks you are possibly casting a base type instance (CRTP<T>) to its derived type (T), which would of course be invalid when dereferenced. You are obviously not doing this, so this may be a bug in the leak detector, or it may be onto something more subtle than what I'm thinking about right now. It may not be an error now, but if Impl becomes a more complicated type (e.g., one with multiple inheritance), it may become an issue (as will your static_cast in the copy-CTOR invocation).
This implementation (with fewer casts) had zero leaks for me as well:
template <typename T>
class CRTP {
protected:
virtual T *internal_copy() const {
return new T(static_cast<const T&>(*this));
}
public:
T *copy() const {
return internal_copy();
}
virtual ~CRTP() = default;
};

Using shared_from_this() in constructor

As you know it is not possible to use the std::enable_shared_from_this and shared_from_this() pair from the constructor of an object since a shared_pointer containing the class is not yet in existance. However, I really would like this functionality. I have attempted my own system and it seems to be working OK.
namespace kp
{
template <class T>
void construct_deleter(T *t)
{
if(!t->_construct_pself)
{
t->~T();
}
free(t);
}
template <class T, typename... Params>
std::shared_ptr<T> make_shared(Params&&... args)
{
std::shared_ptr<T> rtn;
T *t = (T *)calloc(1, sizeof(T));
t->_construct_pself = &rtn;
rtn.reset(t, construct_deleter<T>);
t = new(t) T(std::forward<Params>(args)...);
t->_construct_pself = NULL;
t->_construct_self = rtn;
return rtn;
}
template <class T>
class enable_shared_from_this
{
public:
std::shared_ptr<T> *_construct_pself;
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this()
{
if(_construct_pself)
{
return *_construct_pself;
}
else
{
return _construct_self.lock();
}
}
};
}
Can anyone spot any flaws in this logic? I basically use placement new to assign a pointer to the shared_ptr inside the class before the constructor calls.
As it stands I can use it as so:
std::shared_ptr<Employee> emp = kp::make_shared<Employee>("Karsten", 30);
and in the Employee constructor:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
}
Before I commit this to a relatively large codebase, I would really appreciate some ideas or feedback from you guys.
Thanks!
I know it's been a while but that might be useful to someone with the same issue : the main problem will happen if you attempt to inherit from a class inheriting your enable_shared_from_this.
Especially with this line :
t->_construct_pself = &rtn;
If you have let's say :
class Object : public kp::enable_shared_from_this<Object> {
};
class Component : public Object {
};
Then the compiler won't be able to cast std::shared_ptr<Component>* to std::shared_ptr<Object>* as for the compiler those types are not related even though Component inherits Object.
The easiest solution I see would be to turn _construct_pself to void* like so :
template <class T>
class enable_shared_from_this
{
public:
void* _construct_pself{ nullptr };
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this() const
{
if (_construct_pself)
{
return *static_cast<std::shared_ptr<T>*>(_construct_pself);
}
else
{
return _construct_self.lock();
}
}
};
And then do
t->_construct_pself = static_cast<void*>(&rtn);
It's not very sexy and might make other issues arise but it seems to be working...
[EDIT] There is a slightly better and more "C++" alternative, sorry for not thinking about it right away, just do :
t->_construct_pself = reinterpret_cast<decltype(t->_construct_pself)>(&rtn);
[EDIT2] Make shared_from_this const as it does not change anything in the class
[EDIT3] Found an other issue : If you use a copy constructor via make_shared and use operator= inside the constructor before shared_from_this, shared_from_this will return the address of copied object, not of the object's copy. Only solution I see is to define empty copy constructor and assignment operator for enable_shared_from_this and explicitly call the copy constructor from inheriting classes everytime needed... Either that or MAKE SURE you NEVER call operator= before shared_from_this inside your copy constructor.
I think there is a semantically problem with using shared_from_this() inside the constructor.
The issue is when an exception is being thrown there is no valid object, but you already have setup a shared pointer to it. e.g.:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
if (...) throw std::runtime_error("...");
}
Now Dept will have a pointer to this object, which wasn't successfully created.
Use of shared_from_this() in a constructor should be a code smell, even if it worked, because it is a sign of a possible circular dependency and/or use of a pointer to an incomplete object.
One typically calls shared_from_this() to pass a smart pointer to this object to another object. Doing this during construction would mean that "this" class depends on another component, which depends on "this" class.
Even in the (arguably) valid use case of an object self-registering at some other component, one would be registering an object that is not yet fully constructed, which is a recipe for problems, as pointed out, for example, in this answer.
The solution I would recommend is therefore to analyze the code or design and look for possible circular dependencies, then break that cycle.
In the "self-registering object" use case, consider moving the responsibility of registration somewhere else, for example, to the same place where the object is being instantiated. If necessary, use a "create" function or factory rather than direct construction.

Is there a way to simulate downcasting by reference

So, I have something along the lines of these structs:
struct Generic {}
struct Specific : Generic {}
At some point I have the the need to downcast, ie:
Specific s = (Specific) GetGenericData();
This is a problem because I get error messages stating that no user-defined cast was available.
I can change the code to be:
Specific s = (*(Specific *)&GetGenericData())
or using reinterpret_cast, it would be:
Specific s = *reinterpret_cast<Specific *>(&GetGenericData());
But, is there a way to make this cleaner? Perhaps using a macro or template?
I looked at this post C++ covariant templates, and I think it has some similarities, but not sure how to rewrite it for my case. I really don't want to define things as SmartPtr. I would rather keep things as the objects they are.
It looks like GetGenericData() from your usage returns a Generic by-value, in which case a cast to Specific will be unsafe due to object slicing.
To do what you want to do, you should make it return a pointer or reference:
Generic* GetGenericData();
Generic& GetGenericDataRef();
And then you can perform a cast:
// safe, returns nullptr if it's not actually a Specific*
auto safe = dynamic_cast<Specific*>(GetGenericData());
// for references, this will throw std::bad_cast
// if you try the wrong type
auto& safe_ref = dynamic_cast<Specific&>(GetGenericDataRef());
// unsafe, undefined behavior if it's the wrong type,
// but faster if it is
auto unsafe = static_cast<Specific*>(GetGenericData());
I assume here that your data is simple.
struct Generic {
int x=0;
int y=0;
};
struct Specific:Generic{
int z=0;
explicit Specific(Generic const&o):Generic(o){}
// boilerplate, some may not be needed, but good habit:
Specific()=default;
Specific(Specific const&)=default;
Specific(Specific &&)=default;
Specific& operator=(Specific const&)=default;
Specific& operator=(Specific &&)=default;
};
and bob is your uncle. It is somewhat important that int z hae a default initializer, so we don't have to repeat it in the from-parent ctor.
I made thr ctor explicit so it will be called only explicitly, instead of by accident.
This is a suitable solution for simple data.
So the first step is to realize you have a dynamic state problem. The nature of the state you store changes based off dynamic information.
struct GenericState { virtual ~GenericState() {} }; // data in here
struct Generic;
template<class D>
struct GenericBase {
D& self() { return *static_cast<D&>(*this); }
D const& self() const { return *static_cast<D&>(*this); }
// code to interact with GenericState here via self().pImpl
// if you have `virtual` behavior, have a non-virtual method forward to
// a `virtual` method in GenericState.
};
struct Generic:GenericBase<Generic> {
// ctors go here, creates a GenericState in the pImpl below, or whatever
~GenericState() {} // not virtual
private:
friend struct GenericBase<Generic>;
std::unique_ptr<GenericState> pImpl;
};
struct SpecificState : GenericState {
// specific stuff in here, including possible virtual method overrides
};
struct Specific : GenericBase<Specific> {
// different ctors, creates a SpecificState in a pImpl
// upcast operators:
operator Generic() && { /* move pImpl into return value */ }
operator Generic() const& { /* copy pImpl into return value */ }
private:
friend struct GenericBase<Specific>;
std::unique_ptr<SpecificState> pImpl;
};
If you want the ability to copy, implement a virtual GenericState* clone() const method in GenericState, and in SpecificState override it covariantly.
What I have done here is regularized the type (or semiregularized if we don't support move). The Specific and Generic types are unrelated, but their back end implementation details (GenericState and SpecificState) are related.
Interface duplication is avoided mostly via CRTP and GenericBase.
Downcasting now can either involve a dynamic check or not. You go through the pImpl and cast it over. If done in an rvalue context, it moves -- if in an lvalue context, it copies.
You could use shared pointers instead of unique pointers if you prefer. That would permit non-copy non-move based casting.
Ok, after some additional study, I am wondering if what is wrong with doing this:
struct Generic {}
struct Specific : Generic {
Specific( const Generic &obj ) : Generic(obj) {}
}
Correct me if I am wrong, but this works using the implicit copy constructors.
Assuming that is the case, I can avoid having to write one and does perform the casting automatically, and I can now write:
Specific s = GetGenericData();
Granted, for large objects, this is probably not a good idea, but for smaller ones, will this be a "correct" solution?

C++: Is it possible to call an object's function before constructor completes?

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.