2

我有一个名为Pathextends的类std::vector<Square *>,其中Square也是我创建的一个类。Path它将作为实体穿越 2D 环境的指南。我需要获得最长的路径和最短的路径,因此我希望找到Squares一个Path. 为此,我觉得重载 , 将是有益的std::vector<Square *>::push_back(const value_type &__x),尽管我不确定它的语法是什么。我目前正在尝试这个:

class Path : public std::vector<Square *>
{   //... functional stuff, not relevant. 
    int length;
public:
    push_back(const value_type &__x)
    {   Square *last_square = this->at(this->size() - 1);

        // how do I call super class push_back?
        // however that works, I push back &__x square here.

        Square *most_recent = (Square *)&__x;
        int delta_x = compare_distance(last_square, most_recent);
        length += delta_x;
    };
    int path_length() { return length; };
};

当然,我想我可以只为超类编写一个调用 push_back 的方法,但我觉得重写该函数更简洁,而且学习如何正确重写 stl 函数对我来说是一个好习惯。

谢谢!

4

4 回答 4

18

另外,学习如何正确覆盖 stl 函数对我来说是个好习惯。

事实上,它不是。

STL 容器并不意味着被继承(无virtual方法),因此良好的做法是使用组合并为使用 STL 容器方法的类提供有意义的接口来实现其目标。

于 2012-12-12T09:46:39.107 回答
4

您可以覆盖基类中定义的函数以获得动态多态性- 在运行时确定的类型相关行为。

然而,STL 容器使用模板和非虚拟函数来提供静态多态性——在编译时确定的类型相关行为。没有要覆盖的虚函数,因此从它们继承没有什么意义。

特别是,您的类隐藏了基类函数;任何push_back通过指针/引用调用std::vector而不是Path不会调用您的版本的人,这很可能会导致令人困惑的错误。更好的方法是compisition:

class Path {                        // no inheritance
    std::vector<Square *> squares;  // composition instead
public:
    void push_back(Square * x)      // Don't use __ in identifiers
    {
        squares.push_back(x);
        // do other stuff
    }
};

为了回答代码注释中的问题,如果您确实出于某种奇怪的原因想要使用继承,您可以通过使用基类名称限定成员名称来调用基类版本:

std::vector<Square*>::push_back(x);
于 2012-12-12T10:10:39.990 回答
3

您使用 a 的事实std::vector只是一个实现细节。它也可以是一个std::list,甚至是一个std::set

这应该给你一个线索,即你不应该对这种类型过于强烈地承诺。

聚合而不是继承。你继承被重用,我认为这不是你需要的。

此外,使用标准容器的正确方法是不要从它们继承。它们没有虚拟析构函数,也没有要覆盖的虚拟函数。

于 2012-12-12T10:02:04.530 回答
0

为了增加其他内容,在这种情况下,您将使用组合或私有继承(按条款实现)。

根据经验,提出问题并根据哪个更真实决定使用什么:

  • 路径是根据 std::vector 实现的

或者

  • 路径是一个 std::vector

如果“Path is a std::vector”更准确(因此 Path 不能是 std::list、或 std::deque 或 MyFunnyContainer),则从 std::vector 派生。如果“路径是根据 std::vector 实现的”更准确,请使用组合或私有继承。

于 2012-12-12T12:44:46.097 回答