如何通过派生类函数从基类更改向量

Posted

技术标签:

【中文标题】如何通过派生类函数从基类更改向量【英文标题】:How to change the a vector from a base class via a derived class function 【发布时间】:2020-02-25 06:55:53 【问题描述】:

我创建了一个名为 Shape_2D 的基类,它将被所有形状类继承

Shape_2D.h

private:
    std::vector<Point> points_within_shape_;
    std::vector<Point> points_on_perimeter_;

public:
    std::vector<Point> get_Points_Within_Shape();
    std::vector<Point> get_Points_On_Perimeter();

Shape_2D 类只有 1 个构造函数 Shape_2D.cpp

Shape_2D::Shape_2D(const std::string &name, const bool &contain_Warp_Space)
    : name_(name), contain_warp_space_(contain_Warp_Space) 

std::vector<Point> Shape_2D::get_Points_Within_Shape()

    return this->points_within_shape_;


std::vector<Point> Shape_2D::get_Points_On_Perimeter()

    return this->points_on_perimeter_;

鉴于上面的代码,我想获取一个形状(在本例中为矩形)内的所有点,并让它返回所有点的向量。

该功能针对每个形状单独实现 这个例子是矩形类

矩形.h

    std::vector<Point> get_All_Point_In_Shape() override;
    std::vector<Point> get_All_Point_On_Shape() override;

在 Rectangle 的构造函数中,我立即尝试使用下面定义的函数来分配向量。

矩形.cpp

Rectangle::Rectangle(const std::array<Point, 4> &vertices, const bool &warp_space)
    : Shape_2D("Rectangle", warp_space), vertices_(vertices), area_(compute_Area())

    get_Points_Within_Shape() = get_All_Point_In_Shape();
    get_Points_On_Perimeter() = get_All_Point_On_Shape();


std::vector<Point> Rectangle::get_All_Point_In_Shape()

    std::vector<Point> points_within_shape;
    for (int x = vertices_[0].get_X() + 1; x < vertices_[2].get_X(); x++)
    
        for (int y = vertices_[1].get_Y() + 1; y < vertices_[0].get_Y(); y++)
        
            if (is_Point_In_Shape(x, y))
                points_within_shape.push_back(Point(x, y));
        
    
    return points_within_shape;


std::vector<Point> Rectangle::get_All_Point_On_Shape()

    std::vector<Point> points_on_perimeter;
    for (int x = vertices_[0].get_X(); x <= vertices_[2].get_X(); x++)
    
        for (int y = vertices_[1].get_Y(); y <= vertices_[0].get_Y(); y++)
        
            if (is_Point_On_Shape(x, y))
                points_on_perimeter.push_back(Point(x, y));
        
    
    return points_on_perimeter;

然而,当我通过调试器运行它们时,我发现尽管函数工作正常,但在 Shape_2D 中声明的向量不会相应地更新。我可以做些什么来解决这个问题吗?

【问题讨论】:

要么使成员变量protected 或在基类中提供protected 函数修改。 protectedprivatepublic 之间的中间体,它只扩展了对派生类的访问。 (当然,friend 是另一种选择,但可能不适合您的具体情况。) 你好约苏阿。请提供一些反馈,您是否设法解决了您的问题?给出的答案有帮助吗?如果是,请考虑投票并将其标记为已接受。 【参考方案1】:

您的问题是您将函数 get_Points_Within_Shape()get_Points_On_Perimeter() 定义为返回内部向量的副本。相反,您应该定义它们以将 references 返回到内部向量。此外,此类函数通常有 2 个版本:通常函数返回普通向量和 const 函数返回 const 向量。 IE。您的声明应如下所示:

std::vector<Point>& get_Points_Within_Shape() return points_within_shape_;
const std::vector<Point>& get_Points_Within_Shape() const return points_within_shape_;

【讨论】:

【参考方案2】:

问题是 get_Points_Within_Shapeget_Points_On_Perimeter 方法正在返回点向量的副本,因此您基本上只需分配给该副本,然后在语句执行完成后将其销毁(因为它没有保存到一个变量)。

您的选择是使 points_within_shape_points_on_perimeter_ 受保护,以便派生类可以访问它们(如 cmets 中建议的那样),或者为允许修改数据的 getter 函数提供重载:

std::vector<Point> &get_Points_Within_Shape()

    return points_within_shape_;
    
const std::vector<Point> &get_Points_Within_Shape() const

    return points_within_shape_;

请注意,第一个方法提供了访问数据的能力,因为它返回一个非常量引用。另一种选择是在基类中实现一个 setter:

void set_Points_Within_Shape(const std::vector<Point> &points)

    points_within_shape_ = points;

即使您决定使用 setter,您仍应更改您的 getter 类以返回 const std::vector&lt;Point&gt; &amp;。这样,您不会在每次要读取它们时将所有点复制到一个新向量中。如果向量中有很多点,这可能是主要的性能损失。

附: 虽然这是最简单的方法,但请避免将派生类声明为friend。这应该只在某些特定情况下使用,绝对不能在一个类从另一个类继承的情况下使用。

【讨论】:

以上是关于如何通过派生类函数从基类更改向量的主要内容,如果未能解决你的问题,请参考以下文章

如何从基类向量中获取派生类变量?

从基类类型的向量访问派生类方法

从基类c ++的向量中的派生类调用虚拟方法[重复]

从基类函数派生的类容器

从基类派生类中 C++ 向量的可访问性

如何从基类调用派生类函数?