overriding push_back c++

overriding push_back c++

本文关键字:c++ back push overriding      更新时间:2023-10-16

我有一个名为Path的类,它扩展了std::vector<Square *>,其中Square也是我创建的类。 该Path将用作遍历 2D 环境的实体的指南。 我需要获得最长路径和最短路径,因此我希望找到Path中两个Squares之间的平方数。 为此,我觉得重载是有益的,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 函数对我来说是一个很好的做法。

谢谢!

另外,学习如何正确覆盖 STL 函数对我来说是一种很好的做法。

其实不然。

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

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

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

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

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);

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

这应该给你一个线索,你不应该太强烈地致力于这种类型。

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

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

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

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

  • 路径是按照标准::向量实现

  • 路径是一个标准::向量
如果"Path is a std::vector

"更准确(所以 Path 不能是 std::list 或 std::d eque 或 MyFunnyContainer),则从 std::vector 派生。如果"路径是在 std::vector 的术语中实现的"更准确,请使用组合或私有继承。