【问题标题】:Similar functions produce different outputs相似的功能产生不同的输出
【发布时间】:2015-04-22 10:09:14
【问题描述】:

我正在尝试编译以下文件。 PosLin.cpp 包含下面的 SurTriAuto 和 getSphere 函数。尽管它们相似,但我没有得到相同的结果。是因为“命名空间 TPiecesNS”导致它们不同吗?

我有一个tpieces.h 文件

namespace TPiecesNS
{
  class TPieces
  {
  public:
    TPieces();
    //other stuff
  }
}

tpieces.cpp 有:

void TPieces::addPoint(Vertex* point)
{
    Vertex* p = new Vertex();
    p->Point[0] = point->Point[0]; //similar for Point[1],[2]
    p->Normal[0] = point->Normal[0]; //same for 1,2
    m_Vertices.push_back(p);
}

geopar.h 文件有

#include "tpieces.h"
#include "Geo/Geo.h"

class Geo;

namespace TPiecesNS
{
   class GeoPar;
   {
    public:
          GeoPar();
          TPieces* getSphere(Geo* geo);
          TPieces* getSphere(Geo* geo, int permu);
    private:
      TPieces* SurTriAuto(TPieces* boundary, Geo* geo,int permu);

   }
}

geopar.cpp文件有

#include "tpieces/geo.h"
#include "tpieces.h"
#include "Geo/Geo.h"

using namespace TPiecesNS;

TPieces* GeoPar::getSphere(Geo* geo) {
    return getSphere(geo, 0);
}

TPieces* GeoPar::getSphere(Geo* geo, int permu)
{
TPieces* boundary = new Sphere();
return SurTriAuto(boundary,geo,permu);
}

TPieces* GeoPar::SurTriAuto(TPieces* boundary, Geo* geo, int permu)
{
  double maxx, maxy, maxz, minx, miny, minz;
  double        x,y,z,f,nx,ny,nz;
  int number = 6;

  ofstream file;
  file.open("output.txt");

  boundary->numbpts = geo->m_NumTriVerts;
  boundary->numbtris = geo->m_NumTris; 
  file<<"NumVertices "<<boundary->numbpts<<endl;
  file<<"NumTrianlges "<<boundary->numbtris<<endl;

  for (i = 0 ; i < boundary->numbpts; i++)
  {
    x = geometry->m_TriVerts[i*3+0];
    //also equalities for y,z, but I don't want to type here in order to save space
    nx = geometry->m_TriVertNormals[i*3+0];
        //ny, nz also
    if (x < minx) minx = x;
        //comparisons for y,z also and comparing to maxx, maxy, maxz

    Vertex* point = new Vertex();
        point->Point[0] = x;
        point->Point[1] = y;
        point->Point[2] = z;

    point->Normal[0] = nx; //also assignments for ny, nz
    file<<"xyz normals: "<<point->Point[0]<<endl;
    //I also printed out  y,z,nx,ny,nz
        boundary->addPoint(point);
  }

      for (i = 0 ; i < boundary->numbtris; i++)
 {
    ii = geo->m_Tris[i*3+0]; //assignments for jj, kk also
        if (ii < jj && jj < kk)    { i1 = ii; i2 = jj;  i3 = kk; }
       //similar comparisons for jj and kk also here, but I want to save space
        //...
        if (kk < ii && ii < jj)    { i1 = kk; i2 = ii;  i3 = jj; }  // result in i1 <= i2 <= i3

       Face* facet = new Face();
       facet->Index[0] = i1; //i2, i3 are also assigned
      facet->IndexInR[0] = ii; //jj, kk also

      boundary->addFacet(facet);
    }   /* end facet (i) loop */

 for (i = 0 ; i <boundary->numbtris; i++)
 {
    for(int j=0;j<3;j++)
    {
        int index = boundary->m_Faces[i]->Index[j];
        for(int k=0;k<3;k++)
        {
            file<<boundary->m_Faces[i]->Normal[k]<<" "<<boundary->m_Vertices[index]->Normal[k]<<endl;
            boundary->m_Faces[i]->Normal[k] += boundary->m_Vertices[index]->Normal[k];   
            //ERROR IS  HERE
            file<<boundary->m_Faces[i]->Normal[k]<<endl;
        }
    }
 }  

return boundary;

}

而PosLin.h 有

#include "TPieces/tpieces.h"
#include "TPieces/geoPar.h"
#include "Geo/Geo.h"

struct PosRotAndQ {

  TPiecesNS::TPieces* boundary;
};

class PS{
public: 

  PosExCode computation(Geo* geo, POpinion* opinion, PositionRotation* matterboundary)

  PositionRotation* matterboundary;

}

而PosLin.cpp 有

#include "tpieces/tpieces.h"
#include "Geo/Geo.h"

PosExCode PS::computation(Geo* geo, POpinion* opinion, PositionRotation* matterboundary)

{
    TPiecesNS::GeoPar* perform = new TPiecesNS::GeoPar();
    TPiecesNS::TPieces* boundary = new TPiecesNS::Sphere();
    boundary->sphere = perform->SurTriAuto(boundary, geo,0);//if I comment this line out and the line below and un-comment the 2 getSphere lines below, they do not produce the same output
    boundary->sphereDark[0] = perform->SurTriAuto(boundary, geo,0); \
    //boundary->sphere = perform->getSphere(geo,0);
    //boundary->sphereDark[0] = perform->getSphere(geo,0);
}

我注意到 getSphere 和 SurTriAuto 得到不同的输出,特别是在surface->m_Faces[i]->Normal[k] += surface->m_Vertices[index]->Normal[k];这一行

在输出的文本文件中,在+= 操作发生之前,surface-&gt;m_Faces[i]-&gt;Normal[k] 和 surface-&gt;m_Vertices[index]-&gt;Normal[k] 的值对于 getSphere 和 SurTriAuto 并不相同,即使所有其他值(例如 x、y、 z,index 值)是相同的。

我怀疑这是因为 boundary 指针之一在 GeoPar.cpp 的 getSphere 中的 TPieces* boundary = new Sphere(); 和/或 PosLin.cpp 的 TPiecesNS::TPieces* boundary = new TPiecesNS::Sphere(); 中丢失了值

【问题讨论】:

  • 您的帖子中有很多代码,但不清楚人们会如何看待这个问题。尝试发布MCVE。
  • 我刚刚编辑了 OP
  • 只是想知道有问题的行,评论和取消评论,功能不同,预计会有不同的输出。您已经重载了构造函数(这很好。)但是以一个参数开头的一个将使用两个参数执行其他操作。这些函数中的代码是不同的。
  • 为什么?如果我注释掉SurTriAuto 并改用getSphere,getSphere 会调用SurTriAuto,所以我不明白它们如何产生不同的输出
  • 更新了我的帖子,阅读并回复。

标签: c++ class oop object namespaces


【解决方案1】:

在一种情况下,两个函数都使用相同的 boundary 对象。在另一种情况下,每个函数都使用一个新的 boundary 对象。

您还没有展示TPieces 类的作用,但我假设addPoint 和addFacet 更改了TPieces 类的内容,这样当您将faces 写入文件时第二次调用,您最终会得到第一次调用中保存的faces。

要使这两种情况相同,请尝试在第二次调用中使用不同的boundary 对象。像这样的:

TPiecesNS::GeoPar* perform = new TPiecesNS::GeoPar();
TPiecesNS::TPieces* boundary = new TPiecesNS::Sphere();
boundary->sphere = perform->SurTriAuto(boundary, geo,0);//if I comment this line out and the line below and un-comment the 2 getSphere lines below, they do not produce the same output
TPiecesNS::TPieces* boundary2 = new TPiecesNS::Sphere();
boundary->sphereDark[0] = perform->SurTriAuto(boundary2, geo,0);
//boundary->sphere = perform->getSphere(geo,0);
//boundary->sphereDark[0] = perform->getSphere(geo,0);

【讨论】:

  • 非常感谢您的解释。这两种情况现在产生相似的输出。不过,我还有另一个不相关的问题。在我的输出boundary-&gt;m_Vertices[index]-&gt;Normal[k] 中,第一行显示为 0(当 i=j=k=index=0 时)。这没有意义,因为nx = geo-&gt;m_TriVertNormals[i*3+0]; 然后point-&gt;Normal[0] = nx 为point-&gt;Normal[0] 分配了一个非零值。我还刚刚编辑了 OP 以包含 TPieces.cpp 和 addPoint 函数的相关代码
  • 在你的代码中,你有nx = geometry-&gt;m_TriVertNormals[i*3+0]; 我不确定geometry 来自哪里。不应该是geo吗?我能给出的最佳建议是使用调试器单步执行代码,并确保 nx 在添加时是正确的值,并确保 addPoint 函数正确添加它。
  • 哦,是的,应该是geo。我打错了。我可以使用什么调试器?我已经尝试过 valgrind 和 gdc 但都没有发现任何问题
  • 哪个调试器取决于您的环境。如果你在 Linux 上(从 valgrind 参考猜测),你可以使用 gdb 作为命令行调试器。如果您使用的是 IDE,那么它可能内置了调试器。请注意,调试器不会为您检测问题,您需要在代码的各个行设置断点并在程序到达这些行时检查变量断点。
猜你喜欢
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 2020-04-25
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多