具有 Base Class 类型全局数组的 C++ 多态行为
C++ Polymorphic behaviour with global array of Base Class type
为什么下面的代码能够展示多态行为
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;
}
但是下面的代码会抛出一个错误
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;
}
我注意到当我尝试在 main() 以外的另一个函数中初始化数组的内容时,会调用 Base class'(TwoDShapes) toString() 方法而不是 Derived classes'(圆形和矩形) toString() 方法。
但是当我在 main() 中做同样的事情时,它能够显示多态行为。
下面是我的基础和衍生 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";
}
*编辑 1:包含更完整的代码
c1
和 s1
是函数 test
的局部变量。
一旦完成,您将无法再访问它们。
所以,s2d[i]
包含一个指向测试函数局部变量的指针。这段代码 cout << s2d[i]->toString() << endl;
运行时,测试函数已经终止。所以所有的局部变量都被销毁了。调用已销毁对象的 toString()
函数具有未定义的行为。您无法再访问它们。
问题出在您的 test
函数中,您在其中创建了两个 local 对象(c1
和 s1
)并保存了它们的地址.然而,当那个函数 returns 时,这两个对象的生命周期将结束,并且 s2d[0]
和 s2d[1]
的值将是 dangling pointers.
为什么下面的代码能够展示多态行为
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;
}
但是下面的代码会抛出一个错误
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;
}
我注意到当我尝试在 main() 以外的另一个函数中初始化数组的内容时,会调用 Base class'(TwoDShapes) toString() 方法而不是 Derived classes'(圆形和矩形) toString() 方法。 但是当我在 main() 中做同样的事情时,它能够显示多态行为。
下面是我的基础和衍生 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";
}
*编辑 1:包含更完整的代码
c1
和 s1
是函数 test
的局部变量。
一旦完成,您将无法再访问它们。
所以,s2d[i]
包含一个指向测试函数局部变量的指针。这段代码 cout << s2d[i]->toString() << endl;
运行时,测试函数已经终止。所以所有的局部变量都被销毁了。调用已销毁对象的 toString()
函数具有未定义的行为。您无法再访问它们。
问题出在您的 test
函数中,您在其中创建了两个 local 对象(c1
和 s1
)并保存了它们的地址.然而,当那个函数 returns 时,这两个对象的生命周期将结束,并且 s2d[0]
和 s2d[1]
的值将是 dangling pointers.