是否施放了可覆盖的操作?如果是这样,怎么样?

时间:2012-04-25 16:54:35

标签: c++ casting override

是否可以在C ++中覆盖(C风格)强制转换?

假设我有代码

double x = 42;
int k = (int)x;

我可以让第二行的演员表执行我写的一些代码吗?像

这样的东西
// I don't know C++
// I have no idea if this has more syntax errors than words
operator (int)(double) {
    std::cout << "casting from double to int" << std::endl;
}

我问的原因是因为问题"Is there any way to get gcc or clang to warn on explicit casts?"和我的建议。

4 个答案:

答案 0 :(得分:4)

  

§12.3.1/ 1“类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换(第4节),用于初始化(8.5) ,以及显式类型转换(5.4,5.2.9)。“

是的,我们可以进行转化,但前提是一方或双方是用户定义的类型,因此我们无法为double提供int

struct demostruct {
    demostruct(int x) :data(x) {} //used for conversions from int to demostruct
    operator int() {return data;} //used for conversions from demostruct to int
    int data;
};

int main(int argc, char** argv) {
    demostruct ds = argc; //conversion from int to demostruct
    return ds; //conversion from demostruct to int
}

正如Robᵩ指出的那样,您可以将explicit关键字添加到其中任何一个转化函数中,这需要用户在代码中使用(demostruct)argc(int)ds显式转换它们而不是让他们隐式转换。如果转换为相同类型或从同一类型转换,通常最好将其中一个或两个作为explicit,否则可能会出现编译错误。

答案 1 :(得分:3)

是的,但仅适用于您自己的类型。看看这个:

#include <iostream>
struct D {
  // "explicit" keyword requires C++11
  explicit operator int() { std::cout << __FUNCTION__ << "\n"; }
};

int main () {
  int i;
  D d;
  //i = d;
  i = (int)d;
}

因此,您无法创建double::operator int(),但可以创建MyDouble::operator int()

答案 2 :(得分:2)

您不能为内置类型重载运算符,但您可以为用户定义的类型编写转换运算符:

struct Double {
    double value;
    operator int() const {
        shenanigans();
        return value;
    }
};

由于您的问题源于需要在代码中查找显式强制类型转换,因此请注意C ++具有显式的强制转换运算符。这些不仅比C风格的演员阵容更清晰,而且非常易于搜索:

static_cast<T>(x)      // Cast based on static type conversion.
dynamic_cast<T>(x)     // Cast based on runtime type information.
const_cast<T>(x)       // Add or remove const or volatile qualification.
reinterpret_cast<T>(x) // Cast between unrelated pointer and integral types.

答案 3 :(得分:1)

转换为其他类型是C ++中的可重载运算符(some examples here),但这一事实对您没有帮助。

Stroustrup wanted语言是可扩展的,但不可变。因此,重载操作符只会将操作扩展到新类型,但是您无法重新定义任何旧类型的操作。

但是,为了避免荒谬,(仍然)不允许为内置类型的内置运算符提供新的含义。因此,语言仍然可扩展但不可变。