继承了相同类型的类向量

Inherited class vector of same type identical

本文关键字:向量 同类型 继承      更新时间:2023-10-16

我有一个奇怪的问题。我正在使用自定义类shape与继承的形状,如球体,长方体,…

所有这些形状都存储在

vector <Shape*> shape;

并且一切正常,我可以验证数据是否正确输入。但是,当输入一个新形状时,所有以前输入的相同类型的形状现在都与最新的成员相同。

例如:

一个简单的输入文件可以是

0 0 0 1 1 1
1
1
0 1 1 1 1 2
0 1 0 0 0.75 1
0 1 0 0 -1.25 1
0 1 10 10 10 1

和第一个形状

之后
0 0 0 1 1 1
1
1
0 1 1 1 1 2

相同,在

后面
0 0 0 1 1 1
2
1
0 1 0 0 0.75 1
0 1 0 0 0.75 1

然后继续发散

矢量驻留在shapeconcontainer .cpp和shapeconcontainer . h中的文件,如果您认为问题在另一个文件中请询问。

非常感谢你的帮助。

问候,约翰

#include "ShapeContainer.H"
#include <iostream>
#include <vector>
void ShapeContainer::PrintT3D (ostream & out, ShapeContainer & SC) 
{
  //    Initialize and Assign Counters  //
  unsigned int Vertex_ID = 1;
  unsigned int Curve_ID = 1;
  unsigned int Patch_ID = 1;
  unsigned int Surface_ID = 1;
  unsigned int Shell_ID = 1;
  unsigned int Region_ID = 1;
  for (unsigned int i = 0; i < SC.shape.size(); i++)
    {
            out << "## Shape " << i + 1 << ": " << SC.shape[i]->get_shape_name() << endl;
      SC.shape[i]->prepare_t3d_input(Vertex_ID, Curve_ID, Patch_ID, Surface_ID, Shell_ID, Region_ID, 0);
      out << *SC.shape[i];
    }
}
void ShapeContainer::PrintStat3D (ostream & out, ShapeContainer & SC)
{
  vector <double> LocalCoords;
  vector <double> LocalProps;
  //    Start printing updated Stat3D file //
  out << SC.BoundingBoxDimensions << endl;
  out << SC.shape.size() << endl;
  out << SC.NumberModes(SC) << endl;
  for (unsigned int i = 0; i < SC.shape.size(); i++)
    {
      LocalCoords = SC.shape[i]->get_coords();
      LocalProps  = SC.shape[i]->get_properties();
      out << SC.shape[i]->get_shape_type() << " " << SC.shape[i]->get_mode() << " " << LocalCoords << " " << LocalProps << endl;
    }
}
void ShapeContainer::ThrowOut(ShapeContainer & SC)
{
    for (unsigned int i = 0; i < SC.shape.size(); i++)
    {
            if ((SC.shape[i]->InBoundingBox(SC.BoundingBoxDimensions))==false) {
                SC.shape.erase(SC.shape.begin()+i-1);
                i=i-1;
        }
    }
}
unsigned int ShapeContainer::NumberModes (ShapeContainer & SC)
{
  vector <int> ModesList;
  ModesList.resize(SC.shape.size(),0);
  for (unsigned int i=0;i<ModesList.size();i++) {ModesList[i]=SC.shape[i]->get_mode();}
  sort (ModesList.begin(), ModesList.end());
  unsigned int count=1;
  for(unsigned int i=0;i<ModesList.size()-1;i++)
    {
      if(ModesList[i]!=ModesList[i+1])
    count++;
    }    
  return count;
}

ShapeContainer.H

#ifndef _SHAPECONTAINER_H_
#define _SHAPECONTAINER_H_
#include <iostream>
#include <vector>
#include <math.h>
#include "utils.H"
#include "Shape.H"
#include "Sphere.H"
#include "Cuboid.H"
#include "Ellipsoid.H"
#include "Octahedron.H"
using namespace std;
class ShapeContainer
{
public:
    ShapeContainer(){};
    ~ShapeContainer(){};
    void initialize();
/// Friend of Print Functions ///
void PrintT3D (ostream & out, ShapeContainer & SC);
void PrintStat3D (ostream & out, ShapeContainer & SC);
void ThrowOut(ShapeContainer & SC);
/// Private access functions ///
    void set_BoundingBox(vector <double> BB) {BoundingBoxDimensions = BB;};   // Cooresponds to box at (x,y,z) with dims (dx,dy,dz)
    unsigned int NumberModes (ShapeContainer & SC);
/// Vector-Like Functions ///
    void push_back(Shape* NewShape) {shape.push_back(NewShape);}
private:
vector <double> BoundingBoxDimensions;
vector <Shape*> shape;
};
#endif

当您有两个指针似乎指向相同的数据时,一个典型的情况是实际上确实指向相同的数据。当您有一个变量并使用寻址操作符将指向该变量的指针压入集合中时,通常会出现这种情况。

一个例子:

struct Foo
{
    // Lost of fields
};
int main()
{
    Foo myFoo;
    std::vector<Foo*> allFoo;
    while (std::getline(cin, input))
    {
        myFoo.field1 = parseFirstValueFromString(input);
        myFoo.field2 = parseSecondValueFromString(input);
        allFoo.push_back(&myFoo);
    }
}

在上面的例子中发生的是,第一次将指向myFoo的指针压入向量,但第二次通过循环修改同一个对象,并压入完全相同的指针。

要解决上面的问题,你需要在循环中创建一个完全新的对象实例。这是使用指针和new操作符完成的,如下所示:
int main()
{
    std::vector<Foo*> allFoo;
    while (std::getline(cin, input))
    {
        Foo* myFoo = new Foo;
        myFoo->field1 = parseFirstValueFromString(input);
        myFoo->field2 = parseSecondValueFromString(input);
        allFoo.push_back(myFoo);
    }
}

在上面的代码中,循环中的每次迭代都会创建一个唯一的实例。