相同类型的继承类向量相同

时间:2013-01-10 18:46:39

标签: c++ class vector

我有一个奇怪的问题。我正在使用称为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

然后它继续发散。

矢量位于ShapeContainer.cpp和ShapeContainer.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

1 个答案:

答案 0 :(得分:1)

当你有两个似乎指向相同数据的指针的典型情况是因为实际执行指向相同的数据。当你有一个变量并使用address-of运算符将指向该变量的指针推送到集合中时,通常会出现这种情况。

一个例子:

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 对象实例。这是使用指针和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);
    }
}

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