如何解释显式转换运算符
How to interpret the explicit cast operator
因为我们可以调用显式转换运算符,使用 static_cast、C 风格转换或构造函数风格转换。我很困惑操作员如何准确地解释这三个演员表。
例如,考虑以下代码。 display_balance()
中的 const Money& balance
可以通过三种方式转换为 double。那么这些 cast 解释的是什么。我认为 Money 中只有一个显式转换运算符,因此调用可能是 balance.operator ()
。实在想不通这三个不同的casting是怎么解释的
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
explicit operator double() const { return amount; }
private:
double amount;
};
void display_balance(const Money& balance)
{
std::cout << "The balance is: " << (double)balance << "\n";
std::cout << "The balance is: " << double(balance) << "\n";
std::cout << "The balance is: " << static_cast<double>(balance) << "\n";
}
类型转换
决定如何执行转换的不是转换时使用的语法,而是基于变量类型的上下文。
当编译器发现您正在尝试从 Money
转换为 double
时,它会尝试找出一种方法来完成此操作 - 在每种情况下,它都会使用 Money::operator double()
运算符,因为在每种情况下都将 double
指定为目标类型。
C++ 由于历史原因,几乎总是允许你以多种不同的方式完成一项任务;甚至它的名字都暗示了它最初的目标:extending the C language.
考虑以下语法:
Money balance(100.0);
// C-Style Cast
(double)balance; //< double with value 100.0
// Functional Cast
double(balance); //< double with value 100.0
double{ balance }; //< double with value 100.0
// Static Cast
static_cast<double>(balance); //< double with value 100.0
编译后,您使用的语法实际上没有任何区别;他们都打电话给 Money::operator double()
.
当然,选角总是受制于operator precedence。
注意:虽然在这种情况下所有方法都是相同的,但并非在所有情况下都是如此。
尽可能使用 static_cast
而不是 c-style 或函数式转换 - 您可以阅读更多关于 here.
的原因
显式与隐式类型转换
考虑以下对象:
Money
是你的 class.
Cash
是 Money
的副本,允许隐式转换。
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
// This is an explicit casting operator:
explicit operator double() const { return amount; }
private:
double amount;
};
class Cash
{
public:
Cash() : amount{ 0.0 } {};
Cash(double _amount) : amount{ _amount } {};
// This is an implicit casting operator
operator double() const { return amount; }
private:
double amount;
};
现在考虑以下接受 double
的函数:
void BuySomething(double amount) {}
为了BuySomething()
和Money
,我们必须首先明确地将它转换为double
:
Money money(500.0);
BuySomething(static_cast<double>(money));
BuySomething((double)money);
BuySomething(double(money));
BuySomething(double{ money });
// We can also just call the operator directly:
BuySomething(money.operator double());
但是,我们可以 BuySomething()
和 Cash
而无需首先显式转换它:
Cash cash(500.0);
BuySomething(cash);
// You can still use explicit casting:
BuySomething(static_cast<double>(cash));
BuySomething((double)cash);
BuySomething(double(cash));
BuySomething(double{ cash });
BuySomething(cash.operator double())
这是因为当编译器看到 BuySomething(cash);
时,它知道 BuySomething()
不接受 Cash
- 它接受 double
- 所以它不仅仅是抛出错误,而是试图找出一种将 Cash
转换为 double
的方法,并在此过程中找到我们的转换运算符。
如果您发现我的解释有问题,请在评论中告诉我。
因为我们可以调用显式转换运算符,使用 static_cast、C 风格转换或构造函数风格转换。我很困惑操作员如何准确地解释这三个演员表。
例如,考虑以下代码。 display_balance()
中的 const Money& balance
可以通过三种方式转换为 double。那么这些 cast 解释的是什么。我认为 Money 中只有一个显式转换运算符,因此调用可能是 balance.operator ()
。实在想不通这三个不同的casting是怎么解释的
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
explicit operator double() const { return amount; }
private:
double amount;
};
void display_balance(const Money& balance)
{
std::cout << "The balance is: " << (double)balance << "\n";
std::cout << "The balance is: " << double(balance) << "\n";
std::cout << "The balance is: " << static_cast<double>(balance) << "\n";
}
类型转换
决定如何执行转换的不是转换时使用的语法,而是基于变量类型的上下文。
当编译器发现您正在尝试从 Money
转换为 double
时,它会尝试找出一种方法来完成此操作 - 在每种情况下,它都会使用 Money::operator double()
运算符,因为在每种情况下都将 double
指定为目标类型。
C++ 由于历史原因,几乎总是允许你以多种不同的方式完成一项任务;甚至它的名字都暗示了它最初的目标:extending the C language.
考虑以下语法:
Money balance(100.0);
// C-Style Cast
(double)balance; //< double with value 100.0
// Functional Cast
double(balance); //< double with value 100.0
double{ balance }; //< double with value 100.0
// Static Cast
static_cast<double>(balance); //< double with value 100.0
编译后,您使用的语法实际上没有任何区别;他们都打电话给 Money::operator double()
.
当然,选角总是受制于operator precedence。
注意:虽然在这种情况下所有方法都是相同的,但并非在所有情况下都是如此。
尽可能使用 static_cast
而不是 c-style 或函数式转换 - 您可以阅读更多关于 here.
显式与隐式类型转换
考虑以下对象:
Money
是你的 class.Cash
是Money
的副本,允许隐式转换。
class Money
{
public:
Money() : amount{ 0.0 } {};
Money(double _amount) : amount{ _amount } {};
// This is an explicit casting operator:
explicit operator double() const { return amount; }
private:
double amount;
};
class Cash
{
public:
Cash() : amount{ 0.0 } {};
Cash(double _amount) : amount{ _amount } {};
// This is an implicit casting operator
operator double() const { return amount; }
private:
double amount;
};
现在考虑以下接受 double
的函数:
void BuySomething(double amount) {}
为了BuySomething()
和Money
,我们必须首先明确地将它转换为double
:
Money money(500.0);
BuySomething(static_cast<double>(money));
BuySomething((double)money);
BuySomething(double(money));
BuySomething(double{ money });
// We can also just call the operator directly:
BuySomething(money.operator double());
但是,我们可以 BuySomething()
和 Cash
而无需首先显式转换它:
Cash cash(500.0);
BuySomething(cash);
// You can still use explicit casting:
BuySomething(static_cast<double>(cash));
BuySomething((double)cash);
BuySomething(double(cash));
BuySomething(double{ cash });
BuySomething(cash.operator double())
这是因为当编译器看到 BuySomething(cash);
时,它知道 BuySomething()
不接受 Cash
- 它接受 double
- 所以它不仅仅是抛出错误,而是试图找出一种将 Cash
转换为 double
的方法,并在此过程中找到我们的转换运算符。
如果您发现我的解释有问题,请在评论中告诉我。