Why is the code below able to demonstrate polymorphic behaviour
TwoDShapes* s2d[2];
int main()
{
Circle c1(/*parameter*/);
Rectangle s1(/*parameter*/);
s2d[0] = &c1;
s2d[1] = &s1;
for (int i = 0; i < 2; i )
cout << s2d[i]->toString() << endl;
return 0;
}
BUT the code below throws an error
void test();
TwoDShapes* s2d[2];
int main()
{
test();
for (int i = 0; i < 2; i )
cout << s2d[i]->toString() << endl;
return 0;
}
void test()
{
Circle c1(/*parameter*/);
Rectangle s1(/*parameter*/);
s2d[0] = &c1;
s2d[1] = &s1;
}
I noticed that when I try to initialise the contents of the array within another function other than main(), the Base class'(TwoDShapes) toString() method gets invoked instead of the Derived classes'(Circle and Rectangle) toString() method. But when I do the same thing within main(), it is able to display polymorphic behaviour.
Below is my Base and Derived classes
// Base Class
class TwoDShapes
{
public:
TwoDShapes();
virtual string toString();
string TwoDShapes::toString()
{
return "Inside Base Class toString method";
}
// Derived classes
class Circle : public TwoDShapes
{
public:
Circle(/*parameter*/);
string toString() override;
};
string Circle::toString()
{
return "Inside Circle toString method";
}
*Edit 1: Included a more complete code
CodePudding user response:
c1
and s1
are local variables to function test
.
The moment it finishes, you can no longer access them.
So, s2d[i]
contains a pointer to some local variable of test function. By the time this code cout << s2d[i]->toString() << endl;
runs, the test function already terminated. So all local variables are destroyed. Calling toString()
function of a destroyed object has undefined behavior. You can no longer access them.
CodePudding user response:
The problem is in your test
function, where you create two local objects (c1
and s1
) and save their addresses. However, when that function returns, those two objects' lifetimes will end, and the s2d[0]
and s2d[1]
values will be dangling pointers.