gpt4 book ai didi

数组中对象的 C++ 多态性

转载 作者:IT老高 更新时间:2023-10-28 23:04:07 29 4
gpt4 key购买 nike

我是一名嵌入式软件工程师,来自位和 C 世界。在那个世界里,闪存中有数据,用 C 中的 const 表示。RAM 中有数据。 RAM 昂贵且有限,而闪存便宜且足够。此外,由于碎片问题或安全规定,不允许使用 new、delete、malloc 等进行动态内存分配,最好使用静态设计。

我有大约 2000 个对象,它们具有相似的常量属性但行为不同。所以对他们来说,我将 Shape Class 定义为一个基类,它包含我的对象的共享属性。为了表示不同的行为,Shape Class 有一个名为 Print() 的抽象方法,它将被父级覆盖。

ShapeList 是重要的部分。它是一个 const 数组,由“const Shapes”组成,因此它们将被链接器放入闪存部分。

下面的程序产生一个输出:

I'm a Shape has 3 dots
I'm a Shape has 4 dots
I'm a Shape has 5 dots

虽然预期的输出是:

I'm a Triangle has 3 dots
I'm a Rectangle has 4 dots
I'm a Pentagon has 5 dots

我需要多态行为。当我打印三角形时,它的行为应该像三角形,而不是形状。我该怎么做?

谢谢。

#include <array>
#include <cstdio>
class Shape
{
public:
const int DotCount;
Shape(const int dot): DotCount(dot) {}
virtual void Print(void) const; // this is virtual method
};

void Shape::Print(void) const
{
printf("I'm a Shape has %d dots\n", DotCount);
}

class Triangle: public Shape
{
public:
Triangle(void): Shape(3) { }
void Print(void) const;
};

void Triangle::Print(void) const
{
printf("I'm a Triangle has %d dots\n", DotCount);
}

class Rectangle: public Shape
{
public:
Rectangle(void): Shape(4) { }
void Print(void) const;
};

void Rectangle::Print(void) const
{
printf("I'm a Rectangle has %d dots\n", DotCount);
}

class Pentagon: public Shape
{
public:
Pentagon(void): Shape(5) { }
void Print(void) const;
};

void Pentagon::Print(void) const
{
printf("I'm a Pentagon has %d dots\n", DotCount);
}

const std::array<const Shape, 3> ShapeList = { Triangle(), Rectangle(), Pentagon() };

int main(void)
{
ShapeList.at(0).Print();
ShapeList.at(1).Print();
ShapeList.at(2).Print();
return(0);
}

更多问题:今天我意识到虚函数还有另一个问题。当我将任何虚拟函数添加到基类中时,编译器开始忽略“const”指令并将对象自动放置到 RAM 而不是闪存中。我不知道为什么。我已经向 IAR 提出了这个问题。到目前为止我得到的结论是,即使使用堆,ROMable 类也不可能出现多态行为:/

最佳答案

此版本不使用动态内存:

Triangle tri;
Rectangle rect;
Pentagon pent;
const std::array<const Shape*, 3> ShapeList {
&tri, &rect, &pent
};
for (unsigned int i = 0; i < ShapeList.size(); i++)
ShapeList[i]->Print();

在 C# 等语言中,您可以使用 as 关键字来实现“多态性”。在 C++ 中,它看起来像这样:

    const Triangle* tri = dynamic_cast<const Triangle*>(ShapeList[i]);
if (tri)
static_cast<Triangle>(*tri).SomethingSpecial();

如果dynamic_cast返回的指针有效,可以调用Triangle的特殊函数。例如,这将允许您有一个循环遍历 ShapeList 并仅调用 Triangle 方法。如果可以使用异常,请考虑将其包装在 try catch block 中并捕获 std::bad_cast

注意:您需要一个 const 指针,因为 ShapeList[i] 是 const。 static_cast 之所以必要,是因为您在 const 指针上调用了非常量方法。您可以添加 const 限定符,例如 SomethingSpecial() const,然后只需执行 tri->SomethingSpecial()。否则,您只需将 const 关闭。

例如:

static_cast<Triangle*>(tri)->SomethingSpecial();
// error: static_cast from type 'const Triangle*' to type 'Triangle*'
// casts away qualifiers

这将起作用:

const_cast<Triangle*>(tri)->SomethingSpecial();

关于数组中对象的 C++ 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20764442/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com