如何访问 std::vector 类型的成员

Posted

技术标签:

【中文标题】如何访问 std::vector 类型的成员【英文标题】:How to access members of type std::vector 【发布时间】:2015-11-24 11:02:59 【问题描述】:

我的程序有一个函数来计算一些总和,为此我需要访问向量中对象的属性:

向量声明:

class trilateration 
public:
    ...
    std::vector<tip> *potential;
    ...
;

然后在构造函数中对其进行初始化:

trilateration::trilateration()

...
potential = new std::vector<tip>();
...

类提示如下所示:

class tip 
public:

double sum;
Point2d *pt;
tip();
tip(double x, double y);
virtual ~tip();
;

提示构造函数:

tip::tip(double x, double y)

pt = new Point2d(x,y);
sum=0;

在一些函数中将对象添加到向量中,如下所示:

potential->push_back(tip1);

然后我想像这样访问向量中的一些对象:

void trilateration::get3points()


for(int i=0; i<potential->size(); ++i)

    for(int j=0; j<potential->size(); ++j)
    
        potential[i].sum=potential[i].sum+normalize(potential[i].pt,potential[j].pt);
    



编译时出现以下错误:

error: ‘class std::vector<tip>’ has no member named ‘sum’
error: ‘class std::vector<tip>’ has no member named ‘pt’

如何从向量中访问这些属性?

编辑:

在将电位更改为三边测量的成员并将pt更改为提示的成员后,程序编译但遇到

potential.push_back(tip1);

抛出:

*** glibc detected *** ./loktest: malloc(): memory corruption: 0x00792f10 ***

【问题讨论】:

您需要取消引用,因为potential 是指向vector&lt;tip&gt; 的指针:(*potential)[i]。恕我直言,您根本不应该有指向该向量的指针。 附注:如果没有充分的理由让potential 成为指针,请不要强迫它成为指针。 pttip 也是如此。 【参考方案1】:

除非有强烈理由拥有指针数据成员并使用new 在堆上分配对象,否则不要这样做。

您的代码似乎使用了一种 Java 风格,但这是 C++,而不是 Java。享受 C++ 的自动资源管理,以及 C++ 析构函数的强大功能。只需定义数据成员,无需使用指针和动态分配。

在课堂trilateration,从vector&lt;tip&gt;*更改为vector&lt;tip&gt;

class trilateration 
public:
    ...
    // WAS std::vector<tip> *potential;
    std::vector<tip> potential;
    ...
;

trilateration的构造函数中,不需要动态创建向量;只需删除使用new 分配向量的行:

trilateration::trilateration()

    ...
    // REMOVED:
    // potential = new std::vector<tip>();
    ...

请注意,在您之前的代码中,当您使用 new 分配向量时,您必须在析构函数中正确地 delete 它,并提供正确的复制操作(复制构造函数和复制赋值),或者禁止复制标记上述操作=delete.

相反,如果您有一个普通的简单非指针数据成员,则不需要所有这些复杂的东西。

tip 课程也是如此。 除非有充分的理由拥有 Point2d* 数据成员,否则只需使用 Point2d(非指针)数据成员:

class tip 
public:

  double sum;

  // WAS: Point2d *pt;
  Point2d pt; // <-- note: no pointers here

  tip();
  tip(double x, double y);

  // NOTE: Do you really need a virtual destructor here?? 
  virtual ~tip();
;

也改变构造函数:

tip::tip(double x, double y)
    : pt(x, y), sum(0)

  // REMOVE:
  // pt = new Point2d(x,y);
  //sum=0;

您的代码得到了简化,您将避免一些错误和令人头疼的问题。

【讨论】:

谢谢,代码更正,我已经在我的代码中修正了你指出的内容,我的程序已经编译,但是当我尝试glibc detected 时,我仍然得到glibc detected 任何想法是什么原因造成的? @Cynizm 如果答案有用,请投赞成票。关于您的 glibc 损坏,请使用 minimal, complete and verifiable example 打开一个新问题。【参考方案2】:

由于trilateration::potentialstd::vector&lt;tip&gt;*potential[i] 是位于trilateration::potential + istd::vector&lt;tip&gt;。这不是你想要的。

for(int j=0; j<potential->size(); ++j)

    (*potential)[i].sum=potential[i].sum+normalize((*potential)[i].pt,(*potential)[j].pt);

是一种可能的黑客攻击。但是您真正想要的是摆脱所有那些无用的指针。将向量设为类的成员变量,并在不需要的地方停止使用 new

【讨论】:

使成为会员的潜力,并且还成为会员导致“*** glibc检测到*** ./loktets:malloc():内存损坏:0x00ff2de8 ***” 我无法提供完整的代码,但你有很多工作要做。 @Cynizm 您的代码中可能使用了更多无用的指针。将potential 设为会员本身不应导致此类错误。 当我尝试执行“potential.push_back(tip1);”时出现此错误; @Cynizm:具有这些指针数据成员的类具有虚假的复制语义:您拥有指针的浅拷贝,而不是值的深拷贝。我也不确定你是否有析构函数来释放动态分配的资源。我还写了一个答案,并对您的小费课程进行了修改。您可以使用更合适的 C++ 编码模式(而不是指针和动态分配,当它们不需要时)来避免所有这些令人头疼的问题。

以上是关于如何访问 std::vector 类型的成员的主要内容,如果未能解决你的问题,请参考以下文章

在对象初始化之前访问 C++ std::vector 对象成员

如何创建 C++ 用户定义的类,以便该类的 std::vector 不包含该类的某些成员

如何初始化std :: vector的静态constexpr成员 在c ++ 11中?

pybind11 - 如果访问了结构的任何成员,则 boost::optional 结构的 std::vector 成员将被清空

如何使用 Python 列表在 C++ 中使用 SWIG 分配 std::vector?

如何检查 std::vector 超出范围的访问