0
class CParent {
public:
    void Output() {
        cout << "I'm Parent!" << endl;
    }

    virtual void VirtualOutput() {
        cout << "I'm Parent!" << endl;
    }
};

class CChild : public CParent {
public:
    void Output() {
        cout << "I'm Child!" << endl;
    }

    void VirtualOutput() {
        cout << "I'm Child!" << endl;
    }
};

class CChildChild : public CChild {
public:
    void Output() {
        cout << "I'm ChildChild!" << endl;
    }

    void VirtualOutput() {
        cout << "I'm ChildChild!" << endl;
    }

    void CChildOnly() {
        cout << "I'm only on ChildChild!" << endl;
    }
};

int main() {
    CParent     cp;
    CChild      cc;
    CChildChild ccc;

    CParent* pCP1 = &cp;
    CParent* pCP2 = &cc;
    CParent* pCP3 = &ccc;

    ((CChildChild*)pCP1)->CChildOnly();  //<-this code actually works. HOW? WHY?

    return 0;
}

The pointer variable 'pCP1' is pointing 'cp' which is 'an object of CParent'. So the 'down casting' doesn't make any sense according to what I've learned.

But it works and shows 'I'm only on ChildChild!' with no problem.

The 'cp' has only 'CParent part' on its memory construct. So it can not be 'down casted' as far as I know.

But it works. How?

GamerCoder
  • 139
  • 6
  • 2
    `CChildOnly` doesn't use `this` so it has no clue that you invoked it on the wrong object. You've invoked Undefined Behaviour, and in the set of infinite possible behaviours sits "It Worked!" – user4581301 Dec 21 '21 at 00:44
  • Try with dynamic_cast<> it should throw an error – Moshe Rabaev Dec 21 '21 at 00:45
  • If it throws an error, it won't be at compile time. The C-Style cast used, `(CChildChild*)` turns off all checking because with that cast you're swearing to the compiler that you know exactly what you are doing even if it turns out that you don't. At runtime the behaviour of undefined behaviour is undefined, so maybe you get an error message and maybe you don't. – user4581301 Dec 21 '21 at 00:48
  • Calling `CChildChild::CChildOnly()` on something that is not a valid `CChildChild` "works" in this case for the same reason that [calling a method via a NULL pointer may "work"](https://stackoverflow.com/questions/11320822/). *Undefined behavior* is undefined behavior. – Remy Lebeau Dec 21 '21 at 02:22
  • Does this answer your question? [static\_casting base object's adress to a derived class's pointer](https://stackoverflow.com/questions/45898051/static-casting-base-objects-adress-to-a-derived-classs-pointer) – JaMiT Dec 21 '21 at 02:27
  • @MosheRabaev it did not throw any error. It works – kenash0625 Dec 21 '21 at 09:28
  • It **appears to work** or **it gives my expected result** would be better wording. According to C++ language rules it doesn't work. Note that if you know exactly what you are doing through extensive research, testing on a constrained set of targets and probably years of experience, there is a place for exploiting Undefined Behaviour so long as A) You document the out of it and B) There is no way to meet the requirement with defined behaviour. – user4581301 Dec 21 '21 at 19:19

0 Answers0