2

Compiling f works, but compiling g fails with an error.

Why does this happen?

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

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

void f() {
  A* a = new A();
  B* b = static_cast<B*>(a);
}

void g() {
  A* a = new A();
  B* b = a;
}
sandeep
  • 205
  • 1
  • 3
  • 5
  • 2
    Hang on a sec...you posted a question here http://stackoverflow.com/questions/2483227/why-the-function-from-immediate-parent-is-called-and-not-from-grandparent-class 10 minutes ago....this is frowned upon, if no one responds, do NOT post the same thing again! Voting to Close!!!! – t0mm13b Mar 20 '10 at 13:56
  • 5
    @Tommieb75: These two are different questions. Can you plese checkas I posted two different Qs.If there are any duplicacy that is unintended. – sandeep Mar 20 '10 at 14:03
  • `static_cast` tells the compiler "Trust me, I know this is actually a B*". Doing it in this situation means you're lying to the compiler. – Bill Mar 20 '10 at 15:25
  • 1
    You should add a little explanation of what your problem seems to be before the code itself (and at the same time, having a meaningful title also helps – David Rodríguez - dribeas Mar 20 '10 at 16:58
  • 2
    This question should be reopened. It is not a duplicate. – John Saunders Mar 24 '10 at 20:01
  • Actually, this might be a good case to use dynamic_cast, which of course will return a null-ptr here. – stefaanv Mar 25 '10 at 11:49

5 Answers5

4

A static_cast forces a conversion that is potentially unsafe.

B* b = static_cast<B*>(a);

This would be valid if a pointed to an A object that actually was the base class sub-object of a B object, however it doesn't. The cast forces the conversion.

B* b = a;

There is no cast here and there is (correctly) no implicit conversion allowed from base class pointer to derived class pointer. A pointer to a derived class can always be converted to a pointer to a base class because a derived class object always contains a base class sub-object but not every base class instance is a sub-object of a particular derived class type.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 1
    To anyone thinking of undeleting this question: I believe that it was been closed in error and then possibly deleted as noise. The user posted two questions in quick succession and there was an erroneous assertion that they are duplicates of each other. If you read the content of the questions, this is not the case. This question *may* deserve to be closed, but certainly not because it's an exact duplicate of the asserted duplicate. – CB Bailey Mar 24 '10 at 11:29
3

Well, yeah. Doing:

B* b = new A();

Is unsafe. You end up with a B pointer to an A object; you never construct the B portion of the object; your object is "sliced".

On the other hand...

A* a = new B();

...would be fine.

  • B* b = new A(); doesnt compile... while A *a=new A(); B * b=static_cast(a); compiles..I am trying to do the same thing. – sandeep Mar 20 '10 at 14:01
  • `B* b = a;` doesn't compile because it might be incorrect. In general, the compiler can't know whether or not `a` actually points to an object of type `B`, so it doesn't allow implicit conversions. `static_cast` is a way to force the conversion, but it's wrong to do this if the object isn't of type `B` - trying to use `b` will give undefined behaviour. – Mike Seymour Mar 20 '10 at 14:11
1

You are trying to convert a pointer from A* to B*. I am not sure what you are trying to achieve. But since B* is derived from A* and not the other way around this is not valid. Maybe you want to do something like this:

int main()
{
///The above code compiles while if I replace above two line in main with below assignment it gives error.
     A *a=new A();
    A * b=new B();

}
Lucas
  • 13,679
  • 13
  • 62
  • 94
1

Yes, it does give an error if you want to assign a base class to a derived class pointer type. No, it doesn't give an error if you explicitly cast the pointer type, because in C++ you are allowed to shoot yourself in the foot if you so desire.

What exactly is baffling you, or what did you expect to achieve with your code?

DevSolar
  • 67,862
  • 21
  • 134
  • 209
0

A base class cannot be implicitly converted to a derived class. Just consider this

class A {
  public: int x;
};
class B : public A {
  public: int y;
};
B* b = new A; // assume it works, so 4 bytes is allocated and initialized.
b->y;         // bam! accessing unallocated  region.
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005