static_cast与直接调用转换运算符?

时间:2016-06-04 11:11:00

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

考虑以下类,就像一个简单的例子:

#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并让它完成这项工作?

这两行几乎完全相同(即调用转换运算符),据我所知,它们的行为没有真正的区别。所以这里真正的问题是这是否真实。即使这些看起来和我一样,但仍然可能存在一些可能无法接受的微妙差异。

那些方法之间是否有任何实际差异(包括可能不适用于此示例的方法),除了它们的语法不同的事实?哪一个应该是首选的,为什么?

2 个答案:

答案 0 :(得分:5)

  

那些方法之间是否有任何实际差异

在这种情况下,不是我所知道的,行为明智。

  

(包括可能不适用于此示例的那些)

如果MongoLab具有static_cast<X>(instance_of_Y)类型的转换构造函数,

X也允许转换。对Y的(可能不存在的)转换运算符的显式调用无法使用上述转换构造函数。当然,在这种情况下,Y没有std::string的转换构造函数。

所以,演员阵容更通用,这是我一般喜欢的。此外&#34;将此对象转换为point&#34; 更有意义&#34;调用运算符string&#34; < / em>的。但是如果出于一些非常奇怪的原因你想避免使用转换构造函数,那么显式调用转换运算符就可以实现这一点。

答案 1 :(得分: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),但是它会丢失说“&#34;这里我将对象转换为字符串&#34;”的语义信息。

如果在输出运算符中仅使用转换运算符,您也可以创建一个(私有)函数,将输出流引用作为参数,并直接写入流,并调用该函数来自输出运营商。