回推c++ std::vector中的元素,它们会丢失信息

Pushing back elements in c++ std::vector, they lose information

本文关键字:信息 元素 std c++ vector 回推      更新时间:2023-10-16

我正在处理一个预先存在的代码,并检查它是否有效。

最令我惊讶的是,这些基础类给我带来了麻烦

typedef int Id;
typedef int BcId;
//!  This class gives some common methods to all mesh objects.
class Identifier{
public:
    static const UInt NVAL;
    Identifier(UInt id):id_(id),bcId_(NVAL){}
    Identifier(UInt id, UInt bcId):id_(id),bcId_(bcId){}
    bool unassignedId()const {return id_==NVAL;}
    bool unassignedBc()const {return bcId_==NVAL;}
    Id id() const {return id_;}
    BcId bcId() const {return bcId_;}
    Id getId() const {return id_;}

    protected:
    Id id_;
    BcId bcId_;
};

//!  This class implements a 3D point, the default is z=0 => 2D point
class Point: public Identifier{
public:
    static const UInt ndim = 3;
    Point(): Identifier(NVAL, NVAL){coord_.resize(3);};
    Point(Real x, Real y, Real z=0):Identifier(NVAL, NVAL)
        {coord_.resize(3);coord_[0]=x; coord_[1]=y; coord_[2]=x;}
    Point(Id id, BcId bcId, Real x, Real y, Real z=0):Identifier(id, bcId)
        {coord_.resize(3);coord_[0]=x; coord_[1]=y; coord_[2]=z;}
    void print(std::ostream & out) const;
    Real operator[](UInt i) const {return coord_[i];}
    private:
    std::vector<Real> coord_;
};
void Point::print(std::ostream & out) const
{
out<<"Point -"<< id_ <<"- "<<"("<<coord_[0]<<","<<coord_[1]<<","<<coord_[2]<<")"<<std::endl<<"------"<<std::endl;
}

现在用最简单的测试:

int main()
{
    Point a(1,1,0,0);
    Point b(2,2,0,1);
    Point c(3,3,1,0);
    a.print(std::cout);
    b.print(std::cout);
    c.print(std::cout);
    std::cout<<b.getId()<<std::endl;
    b.print(std::cout); 
    std::vector<Point> points;
    points.resize(3);
    points.push_back(c);
    points.push_back(b);
    points.push_back(a);

    std::cout<<"The points are"<<std::endl;
    for (int i=0; i<3; ++i)
        points[i].print(std::cout);
    std::cout<<std::endl;
}

我得到了输出:

Point -1- (0,0,0)
------
Point -2- (0,1,0)
------
Point -3- (1,0,0)
------
2
Point -2- (0,1,0)
------
The points are
Point -2147483647- (0,0,0)
------
Point -2147483647- (0,0,0)
------
Point -2147483647- (0,0,0)

这里的问题是您使用points.resize(3);而不是points.reserve(3);std::vector:::resize将把向量的大小更改为所提供的大小。如果vector增长,则插入必要的默认构造对象。在这种情况下,这意味着vector的前3个元素是默认构造的,而您放入其中的3个点实际上位于index的[3, 5]中。

如果您调用了std::vector::reserve,那么它将为3个对象分配空间,但不会创建任何默认实例。这意味着当你把这些点往后推时,它们会占用索引的[0, 2]

vector::resize不是正确的函数,它实际上是调整数组的大小,然后push_back添加另一个三个元素。

你可能想用vector::reserve