C++:算术运算符重载
c++: arithmetic operator overload
我有一个名为 HealthPoints
的 class,它有 hp
和 max_hp
成员。我想重载 +
运算符,所以它会像这样工作:
HealthPoints healthPoints1;
healthPoints1 -= 150; /* healthPoints1 now has 0 points out of 100 */
HealthPoints healthPoints2(150);
healthPoints2 -= 160; /* healthPoints2 now has 0 points out of 150 */
healthPoints2 = healthPoints1 + 160; /* healthPoints2 now has 100 points out of 100 */
我成功地让它工作了,但只是按照特定的顺序。如果我把数字放在对象之前,有没有办法让它识别出两者之间的数字并据此采取行动?目前它的工作方式,我得到 healthPoints2
现在有 160 分(满分 160)。
HealthPoints
class:
class HealthPoints {
public:
static const int DEFAULT_MAXHP=100;
static const int DEFAULT_HP=100;
static const int MINIMUM_MAXHP=1;
static const int MINIMUM_HP=0;
explicit operator int() const;
HealthPoints(int maxHP=HealthPoints::DEFAULT_MAXHP);
~HealthPoints() = default; // Destructor set to default
HealthPoints(const HealthPoints&) = default; // Copy Constructor set to default
HealthPoints& operator=(const HealthPoints&) = default; // Assignment operator set to default
HealthPoints& operator+=(const HealthPoints& HP);
HealthPoints& operator-=(const HealthPoints& HP);
class InvalidArgument {};
private:
int m_maxHP;
int m_HP;
friend bool operator==(const HealthPoints& HP1, const HealthPoints& HP2);
friend bool operator<(const HealthPoints& HP1, const HealthPoints& HP2);
friend std::ostream& operator<<(std::ostream& os, const HealthPoints& HP);
};
HealthPoints::HealthPoints(int maxHP) {
if(maxHP < HealthPoints::MINIMUM_MAXHP) {
throw HealthPoints::InvalidArgument();
}
this->m_maxHP=maxHP;
this->m_HP=m_maxHP;
}
HealthPoints operator+(const HealthPoints& HP1, const HealthPoints& HP2) {
return HealthPoints(HP2)+=HP1;
}
HealthPoints operator-(const HealthPoints& HP1, const HealthPoints& HP2) {
return HealthPoints(HP1)-=HP2;
}
HealthPoints& HealthPoints::operator+=(const HealthPoints& HP) {
if(this->m_HP+HP.m_HP>this->m_maxHP) {
this->m_HP=this->m_maxHP;
} else {
this->m_HP+=HP.m_HP;
}
return *this;
}
HealthPoints& HealthPoints::operator-=(const HealthPoints& HP) {
if(this->m_HP-HP.m_HP>HealthPoints::MINIMUM_HP) {
this->m_HP-=HP.m_HP;
} else {
this->m_HP=HealthPoints::MINIMUM_HP;
}
return *this;
}
我不完全确定您 HealthPoints
class 的逻辑,因此请仔细检查下面的代码。不过,我的观点是实施:
friend HealthPoints operator+(const HealthPoints& other, int value);
friend HealthPoints operator+(int value, const HealthPoints& other);
实际上你只需要实现第一个,然后让第二个使用它:
HealthPoints operator+(const HealthPoints& hp, int value) {
HealthPoints ret{hp};
ret.m_HP = std::min(ret.m_maxHP, ret.m_HP + value);
return ret;
}
HealthPoints operator+(int value, const HealthPoints& hp) {
return hp + value;
}
您可以在此处查看实际效果:
int main() {
HealthPoints hp1{100};
hp1 -= 50;
std::cout << "hp1: " << hp1 << "\n";
auto hp2{hp1 + 10};
std::cout << "hp2: " << hp2 << "\n";
auto hp3{10 + hp2};
std::cout << "hp3: " << hp3 << "\n";
}
// Outputs:
// hp1: (max_HP = 100, HP = 50)
// hp2: (max_HP = 100, HP = 60)
// hp3: (max_HP = 100, HP = 70)
在此声明中:
healthPoints2 = healthPoints1 + 160;
您的 +
运算符正在创建一个新的 HealthPoints
对象,该对象是 healthPoints1
的副本,因此对象的 m_maxHP
设置为 100
。然后将 160
添加到该对象,增加其 m_HP
但保留其 m_maxHP
。然后将该对象分配给 healthPoints2
,同时复制 m_HP
和 m_maxHP
值。这就是 healthPoints2
的 m_maxHP
从 150
变为 100
的原因。
在此声明中:
healthPoints2 = 160 + healthPoints1;
您的 +
运算符正在创建一个新的 HealthPoints
对象,其 m_maxHP
设置为 160
。然后将 healthPoints1
添加到该对象,增加其 m_HP
但保留其 m_maxHP
。然后将该对象分配给 healthPoints2
,同时复制 m_HP
和 m_maxHP
值。这就是 healthPoints2
的 m_maxHP
从 150
变为 160
的原因。
如果您希望 operator
仅更新 m_HP
而不是更改 m_maxHP
,您需要添加接受 int
值而不是 HealthPoints
个对象,例如:
HealthPoints& HealthPoints::operator+=(int value) {
m_HP = std::min(m_HP + value, m_maxHP);
return *this;
}
HealthPoints& HealthPoints::operator-=(int value) {
m_HP = std::max(m_HP - value, HealthPoints::MINIMUM_HP);
return *this;
}
HealthPoints operator+(const HealthPoints& HP, int value) {
return HealthPoints(HP) += value;
}
HealthPoints operator+(int value, const HealthPoints& HP) {
return HealthPoints(HP) += value;
}
HealthPoints operator-(const HealthPoints& HP, int value) {
return HealthPoints(HP) -= value;
}
HealthPoints operator-(int value, const HealthPoints& HP) {
return HealthPoints(HP) -= value;
}
然后,将 HealthPoints(int)
构造函数标记为 explicit
以避免在将 int
值传递给需要 HealthPoints
对象的参数时发生不需要的隐式转换。
我有一个名为 HealthPoints
的 class,它有 hp
和 max_hp
成员。我想重载 +
运算符,所以它会像这样工作:
HealthPoints healthPoints1;
healthPoints1 -= 150; /* healthPoints1 now has 0 points out of 100 */
HealthPoints healthPoints2(150);
healthPoints2 -= 160; /* healthPoints2 now has 0 points out of 150 */
healthPoints2 = healthPoints1 + 160; /* healthPoints2 now has 100 points out of 100 */
我成功地让它工作了,但只是按照特定的顺序。如果我把数字放在对象之前,有没有办法让它识别出两者之间的数字并据此采取行动?目前它的工作方式,我得到 healthPoints2
现在有 160 分(满分 160)。
HealthPoints
class:
class HealthPoints {
public:
static const int DEFAULT_MAXHP=100;
static const int DEFAULT_HP=100;
static const int MINIMUM_MAXHP=1;
static const int MINIMUM_HP=0;
explicit operator int() const;
HealthPoints(int maxHP=HealthPoints::DEFAULT_MAXHP);
~HealthPoints() = default; // Destructor set to default
HealthPoints(const HealthPoints&) = default; // Copy Constructor set to default
HealthPoints& operator=(const HealthPoints&) = default; // Assignment operator set to default
HealthPoints& operator+=(const HealthPoints& HP);
HealthPoints& operator-=(const HealthPoints& HP);
class InvalidArgument {};
private:
int m_maxHP;
int m_HP;
friend bool operator==(const HealthPoints& HP1, const HealthPoints& HP2);
friend bool operator<(const HealthPoints& HP1, const HealthPoints& HP2);
friend std::ostream& operator<<(std::ostream& os, const HealthPoints& HP);
};
HealthPoints::HealthPoints(int maxHP) {
if(maxHP < HealthPoints::MINIMUM_MAXHP) {
throw HealthPoints::InvalidArgument();
}
this->m_maxHP=maxHP;
this->m_HP=m_maxHP;
}
HealthPoints operator+(const HealthPoints& HP1, const HealthPoints& HP2) {
return HealthPoints(HP2)+=HP1;
}
HealthPoints operator-(const HealthPoints& HP1, const HealthPoints& HP2) {
return HealthPoints(HP1)-=HP2;
}
HealthPoints& HealthPoints::operator+=(const HealthPoints& HP) {
if(this->m_HP+HP.m_HP>this->m_maxHP) {
this->m_HP=this->m_maxHP;
} else {
this->m_HP+=HP.m_HP;
}
return *this;
}
HealthPoints& HealthPoints::operator-=(const HealthPoints& HP) {
if(this->m_HP-HP.m_HP>HealthPoints::MINIMUM_HP) {
this->m_HP-=HP.m_HP;
} else {
this->m_HP=HealthPoints::MINIMUM_HP;
}
return *this;
}
我不完全确定您 HealthPoints
class 的逻辑,因此请仔细检查下面的代码。不过,我的观点是实施:
friend HealthPoints operator+(const HealthPoints& other, int value);
friend HealthPoints operator+(int value, const HealthPoints& other);
实际上你只需要实现第一个,然后让第二个使用它:
HealthPoints operator+(const HealthPoints& hp, int value) {
HealthPoints ret{hp};
ret.m_HP = std::min(ret.m_maxHP, ret.m_HP + value);
return ret;
}
HealthPoints operator+(int value, const HealthPoints& hp) {
return hp + value;
}
您可以在此处查看实际效果:
int main() {
HealthPoints hp1{100};
hp1 -= 50;
std::cout << "hp1: " << hp1 << "\n";
auto hp2{hp1 + 10};
std::cout << "hp2: " << hp2 << "\n";
auto hp3{10 + hp2};
std::cout << "hp3: " << hp3 << "\n";
}
// Outputs:
// hp1: (max_HP = 100, HP = 50)
// hp2: (max_HP = 100, HP = 60)
// hp3: (max_HP = 100, HP = 70)
在此声明中:
healthPoints2 = healthPoints1 + 160;
您的 +
运算符正在创建一个新的 HealthPoints
对象,该对象是 healthPoints1
的副本,因此对象的 m_maxHP
设置为 100
。然后将 160
添加到该对象,增加其 m_HP
但保留其 m_maxHP
。然后将该对象分配给 healthPoints2
,同时复制 m_HP
和 m_maxHP
值。这就是 healthPoints2
的 m_maxHP
从 150
变为 100
的原因。
在此声明中:
healthPoints2 = 160 + healthPoints1;
您的 +
运算符正在创建一个新的 HealthPoints
对象,其 m_maxHP
设置为 160
。然后将 healthPoints1
添加到该对象,增加其 m_HP
但保留其 m_maxHP
。然后将该对象分配给 healthPoints2
,同时复制 m_HP
和 m_maxHP
值。这就是 healthPoints2
的 m_maxHP
从 150
变为 160
的原因。
如果您希望 operator
仅更新 m_HP
而不是更改 m_maxHP
,您需要添加接受 int
值而不是 HealthPoints
个对象,例如:
HealthPoints& HealthPoints::operator+=(int value) {
m_HP = std::min(m_HP + value, m_maxHP);
return *this;
}
HealthPoints& HealthPoints::operator-=(int value) {
m_HP = std::max(m_HP - value, HealthPoints::MINIMUM_HP);
return *this;
}
HealthPoints operator+(const HealthPoints& HP, int value) {
return HealthPoints(HP) += value;
}
HealthPoints operator+(int value, const HealthPoints& HP) {
return HealthPoints(HP) += value;
}
HealthPoints operator-(const HealthPoints& HP, int value) {
return HealthPoints(HP) -= value;
}
HealthPoints operator-(int value, const HealthPoints& HP) {
return HealthPoints(HP) -= value;
}
然后,将 HealthPoints(int)
构造函数标记为 explicit
以避免在将 int
值传递给需要 HealthPoints
对象的参数时发生不需要的隐式转换。