【问题标题】:static_cast vs. direct call to conversion operator?static_cast 与直接调用转换运算符?
【发布时间】:2016-06-04 11:10:59
【问题描述】:

考虑下面的类,只是一个简单的例子:

#include <iostream>
#include <string>
using namespace std;

class point {
public:
    int _x{ 0 };
    int _y{ 0 };

    point() {}
    point(int x, int y) : _x{ x }, _y{ y } {}
    operator string() const
        { return '[' + to_string(_x) + ',' + to_string(_y) + ']'; }

    friend ostream& operator<<(ostream& os, const point& p) {

        // Which one? Why?
        os << static_cast<string>(p); // Option 1
        os << p.operator string();    // Option 2

        return os;
    }
};

应该直接调用转换运算符,还是直接调用static_cast 并让其完成工作?

这两行几乎会做完全相同的事情(即调用转换运算符),据我所知,它们的行为之间没有真正的区别。所以这里真正的问题是这是否正确。尽管这些对我来说似乎相同,但仍然可能存在细微的差异,人们可能无法理解。

除了语法不同之外,这些方法(包括可能不适用于本示例的方法)之间是否存在任何实际差异?应该首选哪一个?为什么?

【问题讨论】:

    标签: c++ casting static-cast conversion-operator


    【解决方案1】:

    那么这些方法之间有什么实际区别

    在这种情况下,据我所知,行为明智。

    (包括可能不适用于本例的)

    如果X 具有Y 类型的转换构造函数,static_cast&lt;X&gt;(instance_of_Y) 也将允许转换。对Y 的(可能不存在的)转换运算符的显式调用无法使用上述转换构造函数。当然,在这种情况下,std::string 没有 point 的转换构造函数。

    所以,演员阵容更通用,这也是我通常更喜欢的。另外“将此对象转换为类型string“调用运算符string()更有意义。但是,如果出于某种非常奇怪的原因,您想避免使用转换构造函数,那么显式调用转换运算符就可以实现。

    【讨论】:

    • 转换构造函数的优点,没想到。
    【解决方案2】:

    不,您永远不需要直接调用转换运算符成员函数。

    如果您使用的类的实例需要 std::string 对象,则编译器将自动调用转换运算符,如果您使用例如static_cast 将实例转换为 std::string

    简单而愚蠢的例子:

    void print_string(std::string const& s)
    {
        std::cout << s << '\n';
    }
    
    int main()
    {
        point p(1, 2);
    
        print_string(p);  // Will call the conversion operator
        print_string(static_cast<std::string>(p));  // Will call the conversion operator too
    }
    

    最接近直接调用函数的方法是使用static_cast


    在您的特定情况下,对于输出运算符,您应该使用static_cast。原因是语义以及代码的未来读者和维护者(可能包括您自己)。

    当然可以直接调用转换成员函数(您的选项 2),但它会丢失“这里我正在将对象转换为字符串”的语义信息。

    如果转换运算符的唯一用途是在输出运算符中使用,您不妨创建一个(私有)函数,将输出流引用作为参数,并直接写入流,然后调用该函数来自输出运算符。

    【讨论】:

    • “从不” - 基于什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2019-11-03
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 2013-07-26
    相关资源
    最近更新 更多