cplusplusNewbie
cplusplusNewbie

Reputation: 633

how to pass "this" in 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
}

Upvotes: 23

Views: 54535

Answers (7)

empc
empc

Reputation: 142

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

Read this for more information.

Upvotes: 1

Yongjian Wang
Yongjian Wang

Reputation: 112

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.

Upvotes: 0

cchampion
cchampion

Reputation: 7921

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).

Upvotes: 32

Richard Corden
Richard Corden

Reputation: 21721

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
  }
}

Upvotes: 6

aJ.
aJ.

Reputation: 35460

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.
        //   
    }

Upvotes: 0

LeopardSkinPillBoxHat
LeopardSkinPillBoxHat

Reputation: 29421

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.

Upvotes: 13

red.clover
red.clover

Reputation: 1828

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.

Upvotes: 2

Related Questions