Why do we allow the base class to cast to the derived class?

cast base class to derived class c#
cast base class to derived class c
cast base class to derived class java
convert list of derived class to base class java
base class reference derived class object in java
create derived class object from base class c#
convert list of derived class to base class c#
c# assign base class to derived class

We all know that the base class can't be converted to a derived class, but as the code shows, we did, and we got the result B::foo() and A::fun(), how to interpret this Situation? (Why are B::foo() and A::fun()?)

#pragma
#include "pch.h"
#include<iostream>
using namespace std;

class A
{
public:
    void foo()
    {
        printf("A::foo()\n");
    }
    virtual void fun()
    {
        printf("A::fun()\n");
    }
};
class B : public A
{
public:
    void foo()
    {
        printf("B::foo()\n");
    }
    void fun()
    {
        printf("B::fun()\n");
    }
};
int main(void)
{
    A a;
    B *pb = (B*)&a;
    pb->foo();
    pb->fun();
    return 0;
}

This is undefined behavior territory.

You get the same behavior by declaring the B::fun() to be virtual and removing the inheritance from A.

#include<iostream>
using namespace std;

class A
{
public:
    void foo()
    {
        printf("A::foo()\n");
    }
    virtual void fun()
    {
        printf("A::fun()\n");
    }
};
class B
{
public:
    void foo()
    {
        printf("B::foo()\n");
    }
    virtual void fun()
    {
        printf("B::fun()\n");
    }
};
int main(void)
{
    A a;
    B *pb = (B*)&a;
    pb->foo();
    pb->fun();
    return 0;
}

This is likely due to the behavior of the VTable. Since A has a virtual function, it has __vptr storing the location of the VTable, where virtual functions can be looked up. When the void fun() function becomes virtual in B, it means that it follows the __vptr to check the VTable for a pointer to the void fun() function. Since the __vptr in A points to the A VTable, it follows the the pointer to void fun() will point to A::fun().

In other words, you're playing with the how the internal representation of things happen to look and getting lucky based on this internal representation. Similarly pointing a B* and any other piece of memory could work if the memory happens to contain similar enough information to a B that the program could work with it. It will however fail if you try to do more complex stuff (such as accessing variables defined in B).

Why do we allow the base class to cast to the derived class?, The base class and its derived class are related ! Object Oriented Programming languages allow user to copy (assignment statement) the reference Because upcasting is safe, the Java compiler permits you to omit the casting operation� Accept SolutionReject Solution. An instance of a derived class cast to its base class will, of course, invoke a method declared using the 'new keyword with the same name and signature(parameter Type list) defined in the base class. There is a difference in structure, yes, but not a difference in behavior. A derived class cast to its base class is-a base class; and it no longer has access to fields, properties, and methods defined in the derived class.

We all know that the base class can't be converted to a derived class

That's not 100% true. Well, it is true as stated. But then in your example you show us "pointer casts", not "type casts". And these are a bit different. This code is completely valid:

B b;
A* a = (A*)&b;
B* b2 = (B*)a;

The third line is correct, because we know that a is actually pointing to an instance of B. This behaviour is sometimes useful (e.g. a dispatcher).

but as the code shows, we did, and we got the result B::foo() and A::fun(), how to interpret this Situation?

Your code, on the other hand has undefined behaviour inside it. You start with object of type A, you take A* and you downcast it to B*. The compiler will allow you to do that because in general, as I said earlier this actually can be a correct code under certain circumstances (and it is hard for a compiler to detect these). But not in your case, in your case the result of this operation is not defined in terms of the C++ standard.

All in all: you should interpret it as an incorrect code that does random and dangerous stuff. And it needs fixing.

"Converting" between base class and derived class types, It is always allowed for public inheritance, without an explicit type cast. This is Upcasting is transitive: if we derive a Child class from Parent, then Parent pointer � No, there's no built-in way to convert a class like you say. The simplest way to do this would be to do what you suggested: create a DerivedClass(BaseClass) constructor. Other options would basically come out to automate the copying of properties from the base to the derived instance, e.g. using reflection.

Your example invokes undefined behavior by invalid pointer cast.

A a;
B *pb = (B*)&a;

As you are using a C-style cast, it's hard to see which cast is exactly used, that's why C++ introduced specific casts. static_cast and reinterpret_cast both result in UB after any usage of pb, as variable a is NOT an instance of B. Anything that happens from here on now is compilers choice, it can crash, it can work, etc.

As your A class has a virtual method, you can use dynamic_cast, to check at runtime if your pointer points to an instance of B.

if(B* ptr = dynamic_cast<B*>(&a){
   // Use ptr, we know it's not null here
}

dynamic_cast will return a nullptr if the cast fails.

C++ Tutorial: Upcasting and Downcasting - 2020, Traditional explicit type-casting allows to convert any pointer into any other Therefore, dynamic_cast is always successful when we cast a class to one of its of code would produce a compilation error since base-to-derived conversions are� Derived Classes • A derived class inherits member functions of base class. • A derived class can be used anywhere the base class is expected. Derived Classes • A derived class inherits member functions of base class. • A derived class can be used anywhere the base class is expected. • However, a base class CANNOT be used

Type Casting - C++ Tutorials, is nearly what we need. • Derived classes public: Derived objects are accessible by the base class objects Use an explicit cast to convert a base- class pointer to Allowed. – Referring to a derived-class object with a derived- class pointer. As far as the why goes: In general the base pointer is more general than the derived pointer. As such it knows less about the inherited type. A derived pointer cannot be assigned a pointer to a base type without casting simply because it cannot tell if the base pointer is of the Derived type or one of its children.

[PDF] Derived Classes and Inheritance Derived Classes, When it does, you should store the pointer in Let's call the base class of this� Where clsBaseData is the Base Class from which clsDerivedData is made by Inheriting clsBaseData. ListOfDerivedDataObjects is a List(Of clsDerivedData). I have found this useful where I have Lists of several Derived Classes and I would like to operate on a property of the Base Class for all the objects in the Lists of Derived Classes.

Inheritance — What your mother never told you, C++ FAQ, Inheritance in C# enables you to create new classes that reuse, extend, and modify the A derived class can have only one direct base class. No special syntax is necessary because a derived class always contains all the members of a base class. Derived d = new Derived(); // Always OK. Base b = d; Explicit conversions. However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform an explicit conversion, which is called a cast. A

Comments
  • This is undefined behavior at best. Compiler will let you do this, but how the program will behave at runtime is anyone's guess.
  • You can cast /any/ object to another object if you want. This is inherited from C and still there for historical reasons... But that you can do something doesn't mean it's good. Like said, this is undefined behavior. Will likely lead to segmentation faults...
  • normaly when you do something like this you would use dynamic cast and you would define the behaviour of this downcast you can do alot of weird stuff in c++ which result in undifined behaviour c++ is hard and you always have to keep an eye on if the stuff that you are doing makes sense
  • The second line of main() does B *pb = (B*)&a; which forces conversion of the pointer to the base (&a) to a pointer to derived. The compiler doesn't issue a diagostic because your code effectively directs it not to. Since a is not an instance of A, the subsequent usage of pb give undefined behaviour.
  • Just a sidenote: You should not use a C-style cast in C++, use static_cast<>, dynamic_cast<> or reinterpret_cast<> instead.
  • When pb is forced to be converted with B*, why is the virtual function table of pb lookup still A?
  • According to the link I posted: "Consequently, it makes each class object allocated bigger by the size of one pointer." In other words, the pointer to the VTable is stored in the allocated memory for A when A is created. Casting to B does not change the underlying memory which points to As VTable.