how to pass "this" in c++ - c++

I'm confused with the this keyword in C++, I'm not sure that if I'm doing the right thing by passing this. Here is the piece of code that I'm struggling with:
ClassA::ClassA( ClassB &b) {
b.doSth(this);
// trying to call b's routine by passing a pointer to itself, should I use "this"?
}
ClassB::doSth(ClassA * a) {
//do sth
}

You're using it correctly. The this pointer points to the current object instance.
class helper
{
public:
void help(worker *pWorker) {
//TODO do something with pWorker . . .
}
void help2(worker& rWorker) {
//TODO do something with rWorker . . .
}
};
class worker
{
public:
void dowork() {
//this one takes a worker pointer so we can use the this pointer.
helper.help(this);
//to pass by reference, you need to dereference the this pointer.
helper.help2(*this);
}
helper helper;
};
Also, say you declare worker *pW = new worker(). If you call one of the methods (dowork) on the pW object, you will notice that the this pointer and pW have the exact same value (they are both the same address).
(haven't tested that to make sure it builds, but I think it should).

In C++, this is a keyword which is defined as "the pointer to the current object instance". So your code above is correct.
Depending on the inheritance/composition relationship between ClassA and ClassB, there are probably better ways to achieve what you are doing than by using the this pointer.

It's perfectly OK to pass 'this' or '*this' as you are doing.
Lifetime Dangers:
One point about the example you've supplied is that you're calling doSth from the constructor of ClassA. The object that's passed to doSth is possibly a partially constructed object:
class ClassC {
public:
ClassC ()
: m_c ()
{}
int m_c;
};
class ClassA : public ClassC {
public:
ClassA (ClassB & b)
: ClassC ()
, m_b ( b.doSth (this) ) // ClassC constructed
// ClassA members partially init.
{
b.doSth (this); // ClassA members initialized
}
// ...
int m_a;
};
class ClassD : public ClassA {
public:
ClassD(ClassB & b)
: ClassA (b) // Partially init
, m_d ()
{
// ClassC and ClassA constructed
// ClassD members initialized
}
int m_d;
};
There may be problems if doSth uses members that have not yet been initialized:
void ClassB::doSth (ClassA * a) {
int i = a->m_c; // OK m_c is initialized
int j = a->m_a; // Not OK, m_a not initialized when called
// from member initialization list.
int k = static_cast<ClassD*> (a).m_d; // Not OK
}
Using the dynamic type of the object:
Finally, any use of the dynamic type of the object (eg. virtual calls, dynamic_cast, typeid) will have different results on a partially constructed object than on a complete object (and in some case you can have undefined behaviour).
void ClassB::doSth (ClassA * a) {
if (ClassD * d = dynamic_cast<ClassD *> (a))
{
// Never true when called from ClassA::ClassA
}
}

In this case using this will pass a pointer to the caller class, which is A, to b.DoSth. It seems that you are doing it right. this keyword always points to the class instance that you are using it from.

this is a const pointer to its own object. this pointer is nonmodifiable.
ClassA::ClassA( ClassB &b) {
b.doSth(this);
// here 'this' refers to this object ie the instance of ClassA.
// When you pass 'this' to doSth function --> is equivalent to passing
// the instance of current object of ClassA.
//
}

If what you want is to make it the this as in thiscall, or, the actual very first parameter of any member functions (for g++), there is only one way: by the member access operators:
A* a = sth_that_give_you_an_A();
((B*)a)->doSth();
or in your case, if you want to pass the instance of class A to B::doSth.
((B*)this)->doSth();
Or, you may want to cast it to void* first to make your compiler happy.
If this is what you actually want, it is somehow the only way to do that.
However, an instance of class A may not also be an instance of class B. It is very rare that you want actually do this. You should find a proper way that allow you to down cast an instance of A to its subclass B with confidence.
Or otherwise, if you want to call B::doSth on the instance of B, it is just as normal as what you may do.

this is a pointer to the object instance, so what you are doing is correct.
Read this for more information.

Related

c++ how to get a pointer to the current object in another class?

And again a bad-formulted question, but I don't know how to shortly explain this situation:
I have two classes. Let's name them A and B. A has a lot of member variables and methods. B is a struct which has a shared_pointer to an object of type A. Now A has a method that returns an instance of B (with a pointer to the current instance of A).
My problem is, that A is the subclass of C. C has the same method as described above as pure virtual. The code would look like this:
class C {
public:
virtual B mymethod() const =0;
virtual int getMyvar() const =0;
};
class A : public C {
public:
B mymethod() const override;
int getMyvar() const override; //outputs myvar
private:
int myvar;
};
struct B {
std::shared_ptr<C> pointer;
};
B A::mymethod() const {
B instance;
instance.pointer = std::make_shared<A>(*this); //is this wrong?
return instance;
}
My compiler (gcc 4.8.2) creates the executables for the following code, but at runtime I get "Segmentation fault (core dumped)":
void AnotherClass::something() const {
A object;
B instance = object.mymethod();
std::cout << instance.pointer->getMyvar(); //dumps the core womehow?
}
I read about the std::enable_shared_from_this but I could not figure out how it works or if it helps me.
Why do I get the error message and how can I fix this?
From what I have read in the manual, you do:
class A : public C, std::enable_shared_from_this<A> {
public:
B mymethod() override; // Notice the lack of const
private:
int myvar;
};
and then:
B A::mymethod() {
B instance;
instance.pointer = shared_from_this(); // this should be right
return instance;
}
Like this, all the instances of a std::shared_ptr to the same A object will share the same reference counter, and it will be destroyed only when it must be.
EDIT:
Also, notice that your object A must be managed by some other std::shared_ptr before you can call A::mymethod(). I.e. you must create A objects like this:
std::shared_ptr<A> a_obj(new A);
then you can call A::mymethod():
B b_obj = a_obj->mymethod();
EDIT2:
Method A::mymethod() (and consequently, C::mymethod()) can't be const to be able to call the non-const method shared_from_this().
Preliminary problem: how do you down-cast to access myvar ?
Edit: after your edit, this first topic is no longer relevant. I leave it because I used this code in the live demos illustrating how to solve it.
First, the statement that causes the dump can't compile as you gave it:
std::cout << instance.pointer->myvar;
because instance.pointer is a shared_ptr<C> and C has no member myvar.
If downcasting properly with dynamic_pointer_cast<A>(instance.pointer)->myvar (supposing AnotherClass is a friend) it works.
Your shared pointer made a clone: is it your intent ?
This statement:
instance.pointer = std::make_shared<A>(*this); //is this wrong? PERHAP'S !?
creates a clone object obtained by copy construction from *this. So you don't reference the original object A, and hence you don't need std::enable_shared_from_this : the use count of instance.pointer will be 1 because at that moment there's only one reference to the newly created shared object.
Live demo
Or do you want it to reference the original object ?
You then have to change the statement to:
instance.pointer = std::shared_ptr<A>(this); //better ?
But this won't compile because mymethod() is const, so it consider this as being a pointer to const. To compile the statement you must either remove the constness of mymethod() or add constness to B's pointer.
Then it works. B's shared pointer has still a use count of 1, which is again ok. But once this shared_ptr gets out of scope, the use count is 0 and the shared_ptr's destructor will try to delete the object. AS IT WAS INITIALY A LOCAL OBJECT (ON STACK) this causes a runtime error.
Final approach
As you want to have shared pointers to your object, the code of AnotherClass should be something like:
shared_ptr<C> pobject(new A); // create the object from the free store
B instance = pobject->mymethod();
...
And the C class must inherit as follows:
class C : public std::enable_shared_from_this<C>
{...}
And the my method class must initialize the shared_pointer it retures as follows:
//instance.pointer = std::shared_ptr<A>(this); // no, don't do no longer !!
instance.pointer = shared_from_this(); //<===== RETURN A POINTER TO SELF
Then everything works perfectly.
Live demo
It seems to me that you would get a memory error when your objects go out of scope.
When you create your object A and then create your shared_ptr with the this pointer, your counter will be 1 instead of 2 (as you would maybe expect). So A will be destroyed twice, instead of once.
A more correct way of doing this would be create class A as a shared_ptr and initialize the pointer in class B with it (not inside class A). This way the counter will be incremented as you expect and A will be deleted only once.
The class you want to share will need to inherit from enable_share_from_this.
Then you can call share_from_this to obtain a shared pointer to the class you're in.
If you just try and make_shared you just create a separate ownership group that will mean two things will try and delete your object. That will be the cause of your segfault.

how to reinitialize base class in c++

I have derived class and base class. in the constructor of the derived class I have to use the basic constructor of the base class. Then later on I want to re-construct the base class with deiffernet base class constructor :
class A
{
public:
int a, b;
}
class B : public A
{
B() : A()
{
...
//do some calculations to calculate a and b and then
//re-construct class A with the right values.
A(a,b) <--- ????
}
}
how to I do that ?
Constructors are meant to create objects. Hence they are used once. You should create a method to do initialization and call that from constructors.
You could provide a copy and/or move assignment operations in class A.
class A
{
public:
int a, b;
// Copy assignment operator
A& operator=(const A& rhs) {
if(this == &rhs) return *this;
a = rhs.a; b = rhs.b;
return *this;
}
// ...
};
After the above you could reinitialize it using the pattern
BaseClass::operator=(BaseClass(a,b));
which, in your case is
A::operator=(A(a,b));
If your class is an aggregate, or has an implicitly defined copy constructor, you should use those (you don't have to define your own), and use the same reinitialization pattern as above.
As others already pointed out, you can only call inhereted constructors in the initialization list of your current constructor, or (in C++11) delegate to other constructors of your current class. This is the only place where you can initialize your class.
init method
In some cases it makes sense to add in init() method, which re-initializes parts of your class. This is called two-phase-initialization. You will find it in some window-managing-APIs.
It is important to note that your object is then separated into two parts: The one that is usefully initialized in the c'tor, and the other that is initialized in init(). You must (must, must must!) initialize both parts in a way that the object is in a consistent state -- in must never be in an invalid state. As a rule of thumb: If the object is created (by a c'tor), then a destructor call must always possible. Specificly: Don't leave any pointers and handles lying around with random values.
class ChildWindow : Compontent {
shared_ptr<Component> parent_; // builds the component hierarchy
Component[] children_; // child cp'nts, unknown during c'tor
size_t nchildren_; // ...use e vector in real code!
public:
ChildWindow(chared_ptr<>Component> parent)
: parent_(parent),
children(nullptr), nchildren(0) // MUST initialize
{}
void addChild(Component *child) { /*... change children_ ...*/ }
void init() {
if(nchildren > 0) { /* ...throw away old ... */ }
children_ = new Component[...];
// ... init children_ with nulls
}
};
This is only a rough idea where you may use two-phase initialization.
Wrapper
If you really just need to re-initialize everything, a technical solution might to use a simple wrapper class around you real object:
class WindowWrapper {
Window *window_;
public:
WindowWrapper() : window_(nullptr) {}
void reset() { delete window_; window_ = nullptr; }
Window& get() { return *window_; }
Window& operator*() { return get(); }
}
...typed down off-hand, probably some errors in it. This is why there already is such a wrapper in C++11:
unique_ptr<Window> win { new Window{parent, "title"} };
// ..use win...
win.reset( new Window{otherparent, "other title"} };
And if this unique_ptr is not enough you could put this inside the above wrapper.
The error
Just as a side note, To explain what the code you wrote does:
B::B() : A() {
A(a,b); // <--- ????
}
When you type line "????", you create a *temporary object of type A, which disappears on function exit. It does not call any destructor on your current object.
Why does it create a temp object? Well, you can write
A a(a,b);
as a statement and you get a new instance a of class A, constructed with the a c'tor with two arguments. This a you could use in another function call, say func(a);. But you can spare that explicit variable a by just leaving out its name:
func(A(a,b));
calls func with an unnamed ("temporary") object of class A, which disappears at the end of the statement (i.e. ;).
And these kind of temp objects you can create as an expression. And since every expression is also a statement
A(a,b);
is a valid statement -- creating a temp object, which immediately vanishes.
You cannot call the constructor of your superclass except in your initializer list. You have to use composition instead of inheritance if you want to use operations on a differrently constructed A object. If a method changes an already constructed object, it is not a contructor. So either replace the object with a newly constructed one (instead of changing it) or use non constructor methods.
Put the code to compute a and b into a method and use it in the initializer list:
class A {
public:
A(int a, int b): a_(a), b_(b) {}
};
class B : public A
{
public:
B(): A(B::computeA(), B::computeB()) {}
private:
static int computeA();
static int computeB();
};
I have made the methods static to prevent using a partially initialized object.
Although I have to say that the question and the example sound like you are using inheritance to re-use an implementation. In this case, you should not use inheritance but composition and replace the inheritance with a member object.

c++ pointer arguments: does it make sense to create a copy of the value pointed too, then store the copy as pointer again?

I'm migrating a project to c++ because I hit a performance ceiling while developing it in c#. It's my first time using c++, however, and I'm finding myself doing something a lot that doesn't seem quite right...
Consider the following abstracted example:
class ClassC
{
ClassC::ClassC(int option)
{
//do something
}
}
class ClassB
{
ClassC* objC
ClassB::ClassB(ClassC* objC)
{
this->objC = new ClassC(*objC);
}
}
class ClassA
{
void functionA(void)
{
ClassB objB (&ClassC(2));
}
}
ClassA has a function which creates a ClassB. ClassB's constructor accepts a ClassC, objC. objC is passed by reference because ClassC is not a primitive type, but its stored by reference because ClassC has no default constructor. However, because objC is created in static memory and will be destructed when functionA completes, ClassB needs to copy to the value pointed by objC into dynamic memory, then store a pointer to that copy.
This seems very round-a-bout to me, and makes me feel like im approaching something incorrectly. Is this a standard thing to do in c++?
EDIT: Everyone seems to be saying that the line ClassB objB (&ClassC(2)); is incorrect because the value of the ClassC object will be lost before ClassB can make a copy of it. But I have compiled my example and this is not the case. Here is revised, working code:
class ClassC
{
int option;
public:
ClassC::ClassC(int option)
{
this->option = option;
}
int ClassC::getOption(void)
{
return option;
}
};
class ClassB
{
ClassC* objC;
public:
ClassB::ClassB(ClassC* objC)
{
this->objC = new ClassC(*objC);
}
int ClassB::getOption(void)
{
return objC->getOption();
}
};
class ClassA
{
public:
static ClassB functionA(void)
{
return ClassB (&ClassC(2));
}
};
int main(void)
{
ClassB objB = ClassA::functionA();
int test = objB.getOption(); //test = 2, therefore objC was copied successfully.
return 0;
}
Not sure what's your real question, but your code seems fragile. I'd like to rewrite your code as you have shown to this way:
class ClassC
{
explicit ClassC(int option)
// ^^^^^^^^ stop implicit conversion, if constructor takes one parameter
{
//do something
}
};
class ClassB
{
ClassC objC; // store by value instead of pointer.
// Even smart pointer will be better option than raw pointer
explicit ClassB(const ClassC& objC) // pass by const reference instead
: objC(objC) // use member initializer list to initialize members
{
}
};
class ClassA
{
void functionA(void)
{
ClassB objB(ClassC(2));
}
};
Taking the address of a temporary and saving it off for later use is a big no-no.
ClassB objB (&ClassC(2)); // taking address of temporary
Further, even passing a const-reference of a temporary across a function parameter list will not extend the lifetime further than the function invoke. I.e. once the constructor is done firing the reference is toast, so this:
class ClassB
{
const ClassC& objC;
public:
ClassB(const ClassC& objC) : objC(objC)
{
}
};
won't work either. More info can be read here about the details for why.
It would work if you did this:
ClassC objC;
ClassB objB(objC);
but then again, so would your original sample.
One way to have the lifetime of an external object guaranteed is to dynamically allocate the object through smart-pointer ownership. Consider this:
class ClassB
{
std::shared_ptr<ClassC> ptrC;
public:
ClassB(std::shared_ptr<ClassC> ptrC)
: ptrC(ptrC)
{
// access the instance with ptrC->member()
}
};
Now you can do this:
ClassB objB(std::make_shared<ClassC>(2));
and even if objB is value-copied (like in a sort-operation on a container, etc) the shared instance is still intact. The last man out the door turns off the lights (in this case, deletes the shared ClassC object).
Obviously its rather pointless for a single instance that will only be held by a single parent. In that case, I totally concur with other answers that strongly suggest you use move-semantics. If, however, you have a true need for a shared resource this is one way to consider doing it.
EDIT Adding pass-through constructor to ClassB as a trivial example.
I just realized everyone was so harped on assisting you in constructing your ClassC object, that maybe all you need is a way to provide parameters to objC for construction. I.e. Perhaps you fully intend on objB to outright own its own private instance of objC and all you need is a way to get parameters to it for initialization.
This is what a constructor initializer list is made for. See the code below, which (based on your comments, will probably work for you and is much simpler to understand.
class ClassB
{
ClassC objC;
public:
// default constructor. initializes objC with default value
ClassB() : objC(0)
{
}
// explicit pass-through of params to `objC` construction
explicit ClassB(int option) : objC(option)
{
}
};
This makes your code in ClassA simply this:
ClassB objB(2);
This will invoke ClassB::ClassB(int), passing the provided parameter to construction of the internal objC object instance of type ClassC.
Your constructor for ClassC is irrelevant as what will be called is the copy-constructor
class ClassC
{
ClassC(int option) // defines a constructor that takes an int
{
//do something
}
}
class ClassB
{
ClassC* objC
ClassB(ClassC* objC)
{
this->objC = new ClassC(*objC); // dereferences objC calling ClassC::ClassC(const Class& obj) - the default copy constructor.
}
}
class ClassA
{
void functionA(void)
{
ClassB objB (&ClassC(2)); // passing a reference to a temporary ... bad idea, but since it is copied in ClassB (the object, not the pointer), it will appear okay - if your compiler lets this compile (newer ones should/will likely throw an error "cannot take address of rvalue temporary")
}
}
All in all, this code would be better off with many of the suggestions already mentioned, but it was worth noting that the copy-constructor for ClassC is what was called in ClassB.
ClassB objB (&ClassC(2));
This is a bad thing to do. You are getting the address of a temporary object, which will vanish after this line. As already stated, try to use references instead of pointers. Most of the time, you can replace a pointer with a reference, which is a very safe approach (it will never be "NULL").
You could write
class ClassB
{
ClassC& objC;
ClassB::ClassB(const ClassC& objC) :
objC(objC)
{
}
}

Post constructor initialization

I have a set of objects derived from common base, ApiObject. I need to be able to register all ApiObjects in a separate data structure, but I need to have an actual address of the object being created, not the base class (I'm using multiple inheritance).
I can't put the code to register an object in ApiObject constructor, because it does not know the address of the derived object; nor can I put it in the derived classes' constructors, because we have no way of knowing whether we are actually constructing another derived class (e.g. if class B is inherited from A, and both can be constructed).
So the only option I see is to explicitly call the registration function every time we create an object, as in
B* b = new B(...);
RegisterObject(b);
However, this doesn't seem to be a very good solution, as I have to remember to call this function every time.
I suppose I should give more context to explain why I'm doing this. The objects are created via an overloaded new operator, and it needs the object to know the context it was created in (Lua state). E.g.
Foo* object = new(L) Foo(...);
// Foo is derived from ApiObject, and we want ApiObject to have a reference to L
Currently it is done in a somewhat unelegant way - the new operator allocates additional bytes before the object and stores the L pointer in there, along with some additional data to describe the object type. The base class then receives a pointer to this 'metadata' via the init function.
Otherwise, the first thing that comes to mind are virtual functions, but they can't be called from the constructor, so I'd have to register the base ApiObject pointer but only call the virtual function at some later point, and I'm not sure that's prettier than my current implementation.
What is the type required for RegisterObject? If it takes a
Base*, then you can call it from the constructor of Base,
regardless of the final hierarchy. If it takes some other type,
then you want to call it from the constructor of that type; you
do not want to call it from all classes derived from Base,
but only for those derived from whatever type it takes.
If RegisterObject takes a Base*, and you call it from a
function in a derived class, the first thing that will occur is
that the pointer you pass it will be converted to a Base*.
RegisterObject never receives a pointer to the derived object,
only to the Base in the derived object.
You can additionaly derieve every object you want to register from CRTP class, which performs registration, e.g.
template<class T>
struct registarar_t<T>
{
registarar_t()
{
register(derived());
}
T* derieved()
{
return static_cast<T*>(this);
}
}
struct IWantToRegister : registrar_t<IWantToRegister>, ApiObject
{
}
Also, be careful, derived() pointer is right, but object is not yet initialized (accessing it in parent constructor)
Maybe kassak's solution is more elegant, I'm not that advanced, but I'd recommend something like this (register shoudl be called in the constructor so you don't have to write it every time:
#include <iostream>
struct ApiObject;
void registerObj(ApiObject *foo);
struct ApiObject{
public:
ApiObject(std::string n){
name = n;
registerObj(this);
}
std::string name;
};
void registerObj(ApiObject *foo){
std::cout<<"register called on "<<foo->name<<"\n";
}
struct A : public ApiObject{
public:
A(std::string n) : ApiObject(n) {
std::cout<<"init A\n";
}
};
struct B : public ApiObject{
public:
B(std::string n) : ApiObject(n) {
std::cout<<"init B\n";
}
};
int main(){
B *b = new B("b obj");
A *a = new A("a obj");
delete b;
delete a;
}
You can call the registration function from the base constructor. Just make the base destructor virtual. The address will be same for base and derived class. Just don't use the pointer address before the whole object is created.
Once all the objects are fully created, the pointer address can be safely used through virtual functions or dynamic-casted to derived class.

Creating a copy of an instance using a copy constructor within a function that gets the instance passed as the base object

class A {...}
class B : public A {...}
class C : public A {...}
void M(A* a) {
A* aa = new B(* a)
...
}
int main()
{
B b = new B();
M(b);
...
}
So what I want is to do is call the copy constructor of the object ("a") that is passed to M without having to know whether it's of type B or C etc (instead of the "new B( a)" as above).
Of course, I can use dynamic cast and check for a null ptr etc or use typeid, but there must be an easier way?
Thanks in advance.
One way to get the same effect would be to use the clone() pattern. Give class A a virtual function that copies it, overriding that function in each subclass. Pass an instance of A to your function by reference, and then clone it within that function. A bit messy, but works.