如何访问 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<tip>
的指针:(*potential)[i]
。恕我直言,您根本不应该有指向该向量的指针。
附注:如果没有充分的理由让potential
成为指针,请不要强迫它成为指针。 pt
的 tip
也是如此。
【参考方案1】:
除非有强烈理由拥有指针数据成员并使用new
在堆上分配对象,否则不要这样做。
您的代码似乎使用了一种 Java 风格,但这是 C++,而不是 Java。享受 C++ 的自动资源管理,以及 C++ 析构函数的强大功能。只需定义数据成员,无需使用指针和动态分配。
在课堂trilateration
,从vector<tip>*
更改为vector<tip>
:
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::potential
是std::vector<tip>*
,potential[i]
是位于trilateration::potential + i
的std::vector<tip>
。这不是你想要的。
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 成员将被清空