I am learning C and in the tutorial, I came across a point that you can declare a pointer of type Class and assign address of any class object of same type - Quite normal.
I created a class cylinder which has two private double variables and one method to calculate volume.
// Create a class for cylinder
class Cylinder
{
public:
// Consturctor to set radius and height
Cylinder(double r, double h)
{
radius = r;
height = h;
}
//Calculate volute of Cylinder
double volume()
{
return 3.14*radius*radius*height;
}
private:
double radius{1};
double height{1};
};
I added one more class Triangle which also has two double variables and one method to calculate area -
// Class to define traingle
class Triangle
{
public:
// constructor to set base and height
Triangle(double b, double h)
{
base = b;
height = h;
}
// Calculate area of triangle
double area()
{
return 0.5*base*height;
}
private:
double base{1};
double height{1};
};
In main(), I created two objects - one of the each type (i.e. Cylinder and Triangle) and a pointer of Cylinder type. This pointer is pointing to Triangle object. Using Cylinder pointer (p_cyl), I am calling a method which is present in Cylinder class. I was expecting, either code to crash OR call method present in Triangle class. But to my surprise, pcyl called Cylinder's volume method with values of variables present in Triangle class object.
int main()
{
// Create one cylinder and one triangle
Cylinder cylinder1(4,5);
Triangle triangle1(6,9);
// Calculate volume and area
cout<<"Volume is " << cylinder1.volume() << endl;
cout<<"Area is " << triangle1.area() << endl;
// Fun part: Create a pointer of class Cylinder and point it to triangle
Cylinder *pcyl = (Cylinder*)&triangle1;
// Verify if pcyl is really pointing to triangle1
cout << "Address of Traingle" << &triangle1 << endl;
cout << "pcyl is pointing to "<< pcyl << endl;
// Now that pcyl is pointing to triangle, try to invoke method which is not part of the class.
// Expecting a code crash or call "area" function from Triangle.
cout<<"Cross-call result is " << pcyl->volume() << endl;
return 0;
}
I want to know why this behaviour? As pcyl is pointing to memory occupied by Triangle class object, how it is able to fetch Cylinder class's method.
(P.S. Yes, One should not do it in real life but this is to understand behaviour of Class pointers in C )
EDIT: My concern is, how it works out in the memory? I understood that, Casting is something which is borrowed from C and what I am trying is undefined behaviour.
But, pcyl is pointing to a memory which doesn't have code to run instructions created for volume
. The memory (as it is of Triangle
class) have code for area
. pcyl
is able to fetch correct instructions of function volume
even though these instructions are not present at the memory location it is pointing to!
CodePudding user response:
In C , (address of) non virtual functions of a class are not stored in the object of the class. They are statically linked at compile time. Since you are using a pointer of type Cylinder to make function calls, code is generated to call those functions of Cylinder in compile time. But the data contents of the Triangle object is passed, which will lead to unexpected behavior as expected.
CodePudding user response:
I want to know why this behaviour? how it is able to fetch Cylinder class's method.
The program has undefined behavior meaning the program is still in error even if it doesn't say so explicitly and "seems to be working".
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.
So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. The program may just crash.
So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.
1For a more technically accurate definition of undefined behavior see this, where it is mentioned that: there are no restrictions on the behavior of the program.