C++:父对象在不调用方法的情况下更改其id属性
C++: Parent object change their id attribute without method call
正如我在标题中所指出的,这是一个让我非常困惑的问题,但我仍然找不到解决办法。
我创建了一个Point类,它有三个私有属性(_id、_x和_y)以及相关的公共get和set方法。例如,我创建了三个点(G、H、R),其中点G是"父"。点H是点G(克隆)的原型,点R将是集合点(G+H)(点的相加)的结果。
点数样本:
Point G ("pG", 3.5f, 6.5f);
Point H (G.prototype ()); H.setId ("pH");
Point R;
R = G + H;
程序工作正常,但不幸的是,在操作{R=G+H}之后,点G的_id属性变成了点R的克隆属性,我不明白为什么会发生这种情况,因为评估是从右到左进行的(H+,+G,=R)。
问题是为什么G点属性会自行改变?
出现问题的代码:
#include <iostream>
#include <string>
using namespace std;
class Point
{
private:
string _id;
double _x;
double _y;
public:
Point(string id="undefined", double x = 0.00f, double y = 0.00f)
:_id(id), _x(x), _y(y){}
~Point(){}
public:
// Getters methods
string getId() const { return _id;}
double getX() const { return _x; }
double getY() const { return _y; }
void setId(string id) { _id = id; }
// Setters methods
void setX(double n = 0.00f) { _x = n; }
void setY(double n = 0.00f) { _y = n; }
Point prototype() { return Point(_id, _x, _y); }
Point operator+ (const Point& p)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
_id.append("+").append(p._id),
_x+p._x,
_y+p._y
);
}
Point operator= (const Point& p)
{
cout << "Operator = called, returning a new object Point(p._id, p._x, p._y)" << endl;
_id=p._id;
_x=p._x;
_y=p._y;
return *this;
}
};
int main()
{
Point G("G",10.0f, 10.0f);
Point H(G.prototype()); H.setId("H");
Point R;
R = G + H;
cout << "object Point {id: " << G.getId() << ", x: " << G.getX() << ", y: " << G.getY() << "}" << endl;
cout << "object Point {id: " << H.getId() << ", x: " << H.getX() << ", y: " << H.getY() << "}" << endl;
cout << "object Point {id: " << R.getId() << ", x: " << R.getX() << ", y: " << R.getY() << "}" << endl;
return 0;
}
提前感谢!
Point operator+ (const Point& p)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
_id.append("+").append(p._id), // HERE
_x+p._x,
_y+p._y
);
}
在此行中,修改this
对象的_id
属性。根据经验,binary+运算符应该是const成员,或者-IMO-cleaner-一个使用两个const引用参数的静态方法。
顺便说一句,您可以在C++中添加字符串,只需对它们应用+运算符(_id + "+" + p._id
)。
如果将二进制算术运算符实现为成员,则应考虑将该运算符设为const
成员。这将捕捉到实现中的明显修改(实现是越界的,以避免包含不相关的代码):
Point Point::operator+ (const Point& p) const
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
_id.append("+").append(p._id),
_x+p._x,
_y+p._y
);
}
操作_id.append("+")
实际上对this->_id
(即左手操作数的_id
成员)进行操作。由于您的成员运算符不是const
,因此编译器允许您进行修改。这可能不是你想要做的。你可能更想写:
Point Point::operator+ (const Point& p) const
{
cout << "Operator + called, returning a new objectn";
return Point
(
_id + "+" + p._id,
_x+p._x,
_y+p._y
);
}
其创建具有期望值的合适的临时字符串(我还替换了std::endl
的过度使用)。
operator+
过载中的此行:
_id.append("+").append(p._id),
在这里,您必须非常小心,您当前处于一个对象中(在您的示例中,这将是G
对象)。append
实际上改变了本地字符串,所以您的代码是先附加+
,然后再附加p._id
,然后将其深度复制到返回值中。
一个快速的解决方案是将其更改为临时的,以容纳您需要的东西:
_id + "+" + p._id
为了避免将来出现这样的问题,您应该将运算符重载声明为友元方法,这样就可以非常清楚地了解您在操作什么
friend Point operator+ (const Point& lhs, const Point& rhs)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
lhs._id.append("+").append(rhs._id), //COMPILER ERROR! We're modifying the const "lhs"!
lhs._x+rhs._x,
lhs._y+rhs._y
);
}
因此,让我们将其更改为:
friend Point operator+ (const Point& lhs, const Point& rhs)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
lhs._id + "+" + rhs._id, // no longer modifying lhs -- all is well!
lhs._x+rhs._x,
lhs._y+rhs._y
);
}
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在不知道属性具有哪些构造函数的情况下初始化属性?
- C++ - 如何在不调用其属性的情况下调用类?
- 程序在没有输入的情况下退出,它有基本的,驱动的类属性初始化问题
- 具有仅在某些情况下引用外部变量的属性的类
- 如何在不更改代码的情况下为所有C++函数设置属性
- 如何在不使用 C++ 中的管理员权限的情况下设置 AD 属性值
- 在可疑的情况下发出叮当警告:函数'foo'可以用属性"noreturn"声明吗?
- C++:父对象在不调用方法的情况下更改其id属性
- 为什么在这种情况下是this->属性而不是this.attribute(C++OOP)?
- 如何在不擦除 Windows 上C++中的其他属性的情况下隐藏/取消隐藏文件
- 如何在不提供有效生成器的情况下调用 boost::karma::rule 不消耗其属性
- 在c++中是否有一个很好的理由在不改变属性的情况下引用它?