Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the "this" pointer RTTI-enabled?

Tags:

c++

rtti

I'm trying to discover the most-derived class of an object, within a constructor of one of the classes in its inheritance tree. I've spent several hours on this now and am at a loss for how else I can do it or why it doesn't make sense. It seems to make perfect sense, yet it refuses to work. I've found numerous pages about RTTI and gotten basically nowhere with them. I'll continue explaining after my test case and its output.

The source:

#include <iostream>
#include <typeinfo>
#include <string>

class A
{
public:
  A(std::string foo);

  virtual void bar(A* a) = 0;
};

class B : public A
{
public:
  B();

  virtual void bar(A* a);
};

A::A(std::string foo)
{
  std::cout << "type as passed to A constructor: " << foo << " (" << this << ")" << std::endl;
  std::cout << "type as determined in A constructor: " << typeid(*this).name() << " (" << this << ")" << std::endl;
}

B::B() : A(typeid(*this).name())
{
  A* a = (A*)this;
  std::cout << "type as determined in B constructor: " << typeid(*a).name() << " (" << this << ")" << std::endl;
  this->bar(this);
}

void B::bar(A* a)
{
  std::cout << "type as determined in bar: " << typeid(*a).name() << " (" << a << ")" << std::endl;
}

int main()
{
  B b;
  b.bar(&b);

  return 0;
}

The output (on g++):

type as passed to A constructor: 1B (0x7fff5fbff910)
type as determined in A constructor: 1A (0x7fff5fbff910)
type as determined in B constructor: 1B (0x7fff5fbff910)
type as determined in bar: 1B (0x7fff5fbff910)
type as determined in bar: 1B (0x7fff5fbff910)

I'm trying to get the second line of the output to say "1B" instead of "1A". Is the RTTI stripped from "this" for some reason I can't yet imagine? How does that not break the idea of virtual functions? (I had implemented this with virtual functions until I discovered I was reimplementing part of RTTI, which I hadn't known of before.) As the output shows, I can make this work if I avoid using "this," but the need to do that would seem like breakage by design.

like image 965
Grault Avatar asked Jun 20 '12 05:06

Grault


1 Answers

You cannot do that because you misunderstand the dynamics involved.

The rule is:

The this in constructor/destructor of any class points to the class whose constructor/destructor it is.

Also, this is the reason virtual functions called in constructor do not behave as you would normally expect a virtual function to work when using dynamic dispatch.

You should detect the type, after the constructor has been called.You can do so in any of the member functions except the constructor and the destructor.

like image 126
Alok Save Avatar answered Nov 15 '22 07:11

Alok Save