c++ - 如何解释显式强制转换运算符

标签 c++ unary-operator typecast-operator

我们可以使用 static_cast、C 风格的强制转换或构造函数风格的强制转换来调用显式强制转换运算符。我很困惑运算符如何准确地解释这三个转换。

例如,考虑以下代码。 display_balance() 中的 const Money&balance 可以通过三种方式转换为 double。那么这些 Actor 诠释了什么。我认为 Money 中只有一个显式转换运算符,因此调用可能是 balance.operator ()。我真的不明白如何解释这三种不同的 Actor 。

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 风格或函数式转换 - 您可以阅读更多有关原因的信息 here .

显式与隐式类型转换

考虑以下对象:

  • 金钱是你的类(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) {}

为了使用 Money 进行 BuySomething(),我们必须首先将其显式转换为 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());

但是,我们可以使用 CashBuySomething(),而无需先显式转换它:

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 的方法>,并在此过程中找到我们的转换运算符。

如果您发现我的解释有问题,请在评论中告诉我。

关于c++ - 如何解释显式强制转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72142269/

相关文章:

c++ - static_cast<int>(var) 和 *(int*)&var 有什么区别?

c++ - STL算法处理符合条件的前N个元素

c++ - C++ 中涉及一元运算符的表达式求值

c++ - 尽管定义了强制转换运算符,但没有强制转换

C++ 可变参数模板和评估顺序

python - pybind11:使用设置工具链接

c# - 运营商 : "bool++" in C#

python - "return +/- "在 python 中做什么?

postgresql - 如何在 LIKE 搜索中显式转换 ENUM 类型?

postgresql - 在 PostgreSQL 中::做什么?