从一个类到另一个类的类型转换不起作用

分享于2022年07月17日 c++ static-cast 问答
【问题标题】:从一个类到另一个类的类型转换不起作用(Typecasting from one class to another isnot working)
【发布时间】:2022-07-08 12:52:24
【问题描述】:

SI ImperialSystem 的转换工作正常,但相反的工作不起作用。 错误信息: static_cast: cannot convert from ImperialSystem to SI

代码:

#include
#define endl '\n'
using std::cout;
#define MTRTOFEETRATIO 3.28084;

/*
Write two classes to store distances in meter-centimeter and feet-inch systems respectively. Write conversions functions so that the program can convert
objects of both types.
*/
class SI;
class ImperialSystem {
private:
    int mfeet;
    int minch;
public:
    ImperialSystem(int m, int cm) :mfeet{ m }, minch{ cm }{};
    ImperialSystem(float dis) :mfeet{ static_cast(dis) }, minch{ static_cast((dis - mfeet) * 12) } {}
    operator float() {
        return mfeet + minch / 12.0;
    }
    operator SI();
    friend std::ostream& operator <<(std::ostream& out, const ImperialSystem& dis);
};

class SI {
private:
    int mmeter;
    int mcentimeter;
public:
    SI(int m, int cm) :mmeter{ m }, mcentimeter{ cm }{};
    SI(float dis) :mmeter{ static_cast(dis) }, mcentimeter{ static_cast((dis - mmeter) * 12) } {}
    operator ImperialSystem();
    friend std::ostream& operator <<(std::ostream& out, const SI& dis);
};

std::ostream& operator <<(std::ostream& out, const SI& dis) {
    out << " " << dis.mmeter << " m " << dis.mcentimeter << " cm ";
    return out;
}
std::ostream& operator <<(std::ostream& out, const ImperialSystem& dis) {
    out << " " << dis.mfeet << " ft " << dis.minch << " in ";
    return out;
}
ImperialSystem::operator SI() {
    double feet = mfeet + minch / 12;
    double meter = feet / MTRTOFEETRATIO;
    return meter;
}
SI::operator ImperialSystem() {
    double meter = mmeter + mcentimeter / 100.0;
    double feet = meter * MTRTOFEETRATIO;
    return feet;
}


int main() {
    SI s{ 20,35 };
    cout << s << " =  " << static_cast(s) << endl;//this works
    ImperialSystem i{ 10,11 };
    cout << i << " =  " << static_cast(i) << endl;//but this doesnot

    return 0;
}

  • 无法复制。您的代码 compiles as written on GCC trunk 。您使用的是什么编译器和标准版本?
  • 您在 ImperialSystem 上的 operator float 可能会使构造函数模棱两可。
  • 该代码缺少大量 const 限定符。将 const 添加到所有内容中,然后仅在无法使用 const 时将其删除。
  • 使用转换构造函数代替强制转换怎么样?或者,更好的是,按照@PaulMcKenzie 的建议行事。
  • operator SI(); -- 我建议你有一个 toSI() 和一个 toImperialSystem() 函数,而不是难以维护的转换运算符。当代码变得更复杂时,如果您坚持使用强制转换运算符,即使您也会忘记实际调用了哪个函数。请注意,即使是标准 C++ 库也没有大量使用(如果有的话)——例如,使用 std::string::c_str() 而不是 const char *() 转换函数。是的,这些演员阵容“看起来很酷”,但根据我的经验,它们会导致更多的错误和代码走上你没想到的道路。

【解决方案1】:

删除,

运算符浮动(){ 返回 mfeet + minch / 12.0; }

来自您的 SI 班级。

这会在 msvs 和 clang 编译器中造成构造和转换的混乱。