如何创建可以访问私有成员和 operore += 符号的辅助函数?
How do I create a helper function that can access a private member and operatore += sign?
我的问题在最下面
我正在为标记创建一个模块以封装在 0 到 100 之间。
到目前为止,我有几个运算符和转换重载函数:
class Mark {
int mark;
public:
Mark(); //constructor
~Mark(); //deconstructor
Mark(int value); // mark is created using int value that sets the value of mark
void setEmpty(); // mark = 0
bool isValid()const; //checks if mark is valid
//type conversion
operator int() const; // mark casted to an int. result would be value of the mark or zero if mark is invalid
operator double() const; //mark casted to a double for gpa..equivalent of int value
operator char() const; // mark casted to char type...result would be grade latter value of mark
//binary member operator
Mark& operator += (int w); // int is added to the value of mark
Mark& operator = (int i); // mark is set to an integer
};
这是主程序:
这是输出:
这是我的问题
我正在尝试为一个整数添加标记,return 该整数和任何无效标记都不会为该整数添加任何值。在主程序中,这是代码,它是最后两行。
Mark n(80), k(120);
cout << (val += n) << endl;
cout << (val += k) << endl;
输出为
140
140
如果他们说我上面的 += 运算符不明确,我就无法创建它。所以我在想这需要一个辅助函数吗?
关于如何执行此操作的任何帮助?
你的隐式转换削弱了你的类型。它是如此的弱,以至于现在变得模棱两可。由于您允许 Mark 自动转换为 int
,因此您也可以只使用 int
并创建 stand-alone 函数来操作 int
而不是 [=15] =]s.
如果您坚持要操纵 Mark
,您应该创建一个具有较小接口的类型来强制执行您的不变量。我不知道那些是什么,但假设 Mark
必须是 [0, 100]
中的 int
。以下类型 (class) 将确保您无法使用该范围之外的值创建 Mark
。任何附加功能都作为 stand-alone 函数添加,该函数采用 Mark
并操纵其 value
并确信这样的值永远不会在 [0,100]
之外,因为这是不可能的它超出了范围。
#include <iostream>
#include <stdexcept>
class Mark {
public:
Mark(int value = 0) {
validate(value);
m_value = value;
}
int value() const { return m_value; }
void clear() { m_value = 0; }
// I don't know why you need in-place modifications, but here they are and
// they are exception safe.
Mark& operator+=(const Mark& other) {
int new_value = value() + other.value();
validate(new_value);
m_value = new_value;
return *this;
}
Mark& operator-=(const Mark& other) {
int new_value = value() - other.value();
validate(new_value);
m_value = new_value;
return *this;
}
private:
void validate(int value) const {
// place your own logic here -- the purpose is to ensure that a Mark cannot
// exist unless it is in a valid state.
if (value < 0 || value > 100) {
throw std::runtime_error("value must be in [0, 100]");
}
}
int m_value = 0;
};
double to_double(const Mark& mark) {
// replace with your own logic
return mark.value() / 100.0;
}
char to_char(const Mark& mark) {
// replace with your own logic
if (mark.value() > 0 && mark.value() < 50) {
return 'D';
} else if (mark.value() >= 50 && mark.value() <= 100) {
return 'A';
} else {
return 'X';
}
}
std::ostream& operator<<(std::ostream& os, const Mark& m) {
// replace with your own logic
return os << "Mark(" << m.value() << ") / " << to_double(m) << " / "
<< to_char(m);
}
int main() {
Mark m;
Mark n(25);
Mark k(100);
// Mark p(-10); // uncommented will throw exception
std::cout << m << "\n"
<< n << "\n"
<< k << "\n"
// << p << "\n" // uncommented will throw exception
;
}
示例输出:
$ clang++ example.cpp -std=c++2a
$ ./a.out
Mark(0) / 0 / X
Mark(25) / 0.25 / D
Mark(100) / 1 / A
我的问题在最下面
我正在为标记创建一个模块以封装在 0 到 100 之间。
到目前为止,我有几个运算符和转换重载函数:
class Mark {
int mark;
public:
Mark(); //constructor
~Mark(); //deconstructor
Mark(int value); // mark is created using int value that sets the value of mark
void setEmpty(); // mark = 0
bool isValid()const; //checks if mark is valid
//type conversion
operator int() const; // mark casted to an int. result would be value of the mark or zero if mark is invalid
operator double() const; //mark casted to a double for gpa..equivalent of int value
operator char() const; // mark casted to char type...result would be grade latter value of mark
//binary member operator
Mark& operator += (int w); // int is added to the value of mark
Mark& operator = (int i); // mark is set to an integer
};
这是主程序:
这是输出:
这是我的问题
我正在尝试为一个整数添加标记,return 该整数和任何无效标记都不会为该整数添加任何值。在主程序中,这是代码,它是最后两行。
Mark n(80), k(120);
cout << (val += n) << endl;
cout << (val += k) << endl;
输出为
140
140
如果他们说我上面的 += 运算符不明确,我就无法创建它。所以我在想这需要一个辅助函数吗?
关于如何执行此操作的任何帮助?
你的隐式转换削弱了你的类型。它是如此的弱,以至于现在变得模棱两可。由于您允许 Mark 自动转换为 int
,因此您也可以只使用 int
并创建 stand-alone 函数来操作 int
而不是 [=15] =]s.
如果您坚持要操纵 Mark
,您应该创建一个具有较小接口的类型来强制执行您的不变量。我不知道那些是什么,但假设 Mark
必须是 [0, 100]
中的 int
。以下类型 (class) 将确保您无法使用该范围之外的值创建 Mark
。任何附加功能都作为 stand-alone 函数添加,该函数采用 Mark
并操纵其 value
并确信这样的值永远不会在 [0,100]
之外,因为这是不可能的它超出了范围。
#include <iostream>
#include <stdexcept>
class Mark {
public:
Mark(int value = 0) {
validate(value);
m_value = value;
}
int value() const { return m_value; }
void clear() { m_value = 0; }
// I don't know why you need in-place modifications, but here they are and
// they are exception safe.
Mark& operator+=(const Mark& other) {
int new_value = value() + other.value();
validate(new_value);
m_value = new_value;
return *this;
}
Mark& operator-=(const Mark& other) {
int new_value = value() - other.value();
validate(new_value);
m_value = new_value;
return *this;
}
private:
void validate(int value) const {
// place your own logic here -- the purpose is to ensure that a Mark cannot
// exist unless it is in a valid state.
if (value < 0 || value > 100) {
throw std::runtime_error("value must be in [0, 100]");
}
}
int m_value = 0;
};
double to_double(const Mark& mark) {
// replace with your own logic
return mark.value() / 100.0;
}
char to_char(const Mark& mark) {
// replace with your own logic
if (mark.value() > 0 && mark.value() < 50) {
return 'D';
} else if (mark.value() >= 50 && mark.value() <= 100) {
return 'A';
} else {
return 'X';
}
}
std::ostream& operator<<(std::ostream& os, const Mark& m) {
// replace with your own logic
return os << "Mark(" << m.value() << ") / " << to_double(m) << " / "
<< to_char(m);
}
int main() {
Mark m;
Mark n(25);
Mark k(100);
// Mark p(-10); // uncommented will throw exception
std::cout << m << "\n"
<< n << "\n"
<< k << "\n"
// << p << "\n" // uncommented will throw exception
;
}
示例输出:
$ clang++ example.cpp -std=c++2a
$ ./a.out
Mark(0) / 0 / X
Mark(25) / 0.25 / D
Mark(100) / 1 / A