C++向量、排序和自定义类运算符
我很困惑,因为我无法弄清楚我的错误/问题在哪里。 我有一个类指令,它使用两个自定义运算符,一个赋值运算符和一个比较运算符。 以前,我仅使用比较运算符,以便使用 std::sort 根据指令的成员之一(即 std::string 名称)对指令进行排序。 然而,自从我开始重构整个项目后,我将一些成员更改为常量。这导致我必须对这些常量使用初始化列表。 这反过来又导致我必须创建一个赋值运算符,因为这些指令在推回到向量中时会被复制。 这就是一切出错的地方。 我包括我的类声明以及构造函数和运算符。
指令.hpp
class Instruction
{
private:
unsigned int param_size;
const float max_angle, min_angle;
bool micro_mutated;
protected:
const std::string body_part;
std::vector<Parameter <float> > parameters;
public:
Instruction(std::string name, float max, float min);
Instruction operator=(const Instruction& I);
bool operator<(const Instruction& I) const;
//there are a few more functions but are completely irrelevant
}
指令.cpp:
Instruction::Instruction(std::string name,float max, float min) :
body_part (name), max_angle(max), min_angle(min)
{}
Instruction Instruction::operator=(const Instruction& I)
{
(*this) = I;
return (*this);
}
bool Instruction::operator<(const Instruction& I) const
{
return body_part < I.body_part;
}
我创建赋值运算符(说实话我以前从未这样做过)的唯一原因是因为当我尝试push_back指令时,编译器抱怨无法“从这里”实例化指示,我认为这与固定成员有关。如果成员不固定,一切都会顺利进行,甚至包括排序。 现在是奇怪的部分。如果我删除 std::sort,上面的代码可以工作,但并非总是有效。有时一段时间后就崩溃了,有时则不会崩溃。但当我进行排序时,它立即崩溃了。 有人可以帮忙吗?
I am puzzled because I cannot figure where my bug/problem is.
I have a class Instruction, which uses two custom operators, one assignment and one comparison operator.
Previously I only used the comparison operator in order to use std::sort to sort Instructions based on one of their members, an std::string name.
However, since I started re-factoring the entire project, I changed some members to constant. This lead me to having to use an initialization list for those constants.
This in turn, lead me to have to create an assignment operator, because those instructions are being copied when pushed back in vectors.
This is where everything goes wrong.
I include my Class declaration and Constructor and Operators.
instruction.hpp
class Instruction
{
private:
unsigned int param_size;
const float max_angle, min_angle;
bool micro_mutated;
protected:
const std::string body_part;
std::vector<Parameter <float> > parameters;
public:
Instruction(std::string name, float max, float min);
Instruction operator=(const Instruction& I);
bool operator<(const Instruction& I) const;
//there are a few more functions but are completely irrelevant
}
instruction.cpp:
Instruction::Instruction(std::string name,float max, float min) :
body_part (name), max_angle(max), min_angle(min)
{}
Instruction Instruction::operator=(const Instruction& I)
{
(*this) = I;
return (*this);
}
bool Instruction::operator<(const Instruction& I) const
{
return body_part < I.body_part;
}
The only reason why I created an assignment operator (which to be honest I've never done before) was because when I was trying to push_back Instructions, compiler complained about not being able to instantiate "from here" Instructions and I thought it had to do with the constant members. Without the members being constant, everything worked fine, even the sorting.
Now the weird part. If I remove the std::sort, the above code works, but not all the time. Some times it crashed after a while, some times it won't crash. But the moment I include the sorting, it crashes straight away.
Can someone please help ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要忘记三原则:如果您有复制构造、复制赋值运算符和析构函数之一,那么您应该拥有它们全部。
然而,您的复制赋值运算符实际上是一个无限循环;它自称。只要您有任何以下形式的内容,就会使用 Operator=:
Instruction &=Instruction&
。这正是(*this) = I
的意思。我的问题是:为什么这些事情是不变的?让成员有效地保持常量意味着您不能通过复制赋值来复制对象(除非您使用 const 强制转换)。您可以复制构造它们,但仅此而已。
这些成员有什么理由保持不变吗?如果是这样,那么您不应该通过赋值来复制这些对象。两者是相互排斥的。
如果您需要一个成员有效地保持不变,不能被外部活动更改(但不是防止复制的语言常量),那么应该使用正确的访问器方法来完成。为类的用户提供获取这些值的方法,但不提供设置它们的方法。
Don't forget the rule of threes: if you have one of a copy construct, copy assignment operator, and destructor, then you should have all of them.
However, your copy assignment operator is effectively an infinite loop; it calls itself. Operator= will be used whenever you have anything of the form:
Instruction &=Instruction&
. Which is exactly what(*this) = I
is.My question is this: why are those things constant? Having members be constant effectively means that you cannot copy the object (unless you use a const-cast) with copy assignment. You can copy construct them, but that's about it.
Is there some reason for those members to be constant? And if so, then you shouldn't be copying these objects by assignment. The two are mutually exclusive.
If you need a member to be effectively constant, unchangable by outside activity (but not language-const which prevents copying), then this should be done with proper accessor methods. Provide users of the class with ways to get these values, but not ways to set them.