【问题标题】:User defined type conversions in C++C++ 中的用户定义类型转换
【发布时间】:2016-09-23 17:30:10
【问题描述】:

我是 C++ 新手

以下是将英制距离(英尺'英寸')的对象转换为米的代码,反之亦然

#include <iostream>
using namespace std;

class Distance
{
private:
    const float MTF;
    int feet;
    float inches;
public:
    Distance() : feet(0), inches(0.0), MTF(3.280833F) //no argument constructor
    { }
    Distance(float meters) : MTF(3.28033F)//(1-arg constructor)
    {//coverting metres to distance object
        float fltfeet = MTF * meters;
        feet = int(fltfeet);
        inches = 12*(fltfeet-feet);
    }
    Distance(int ft, float in) : feet(ft), inches(in), MTF(3.280833F)
    { }
    void getdist()//get distance from user
    {
        cout << "\nEnter feet: "; cin >> feet;
        cout << "Enter inches: "; cin >> inches;
    }
    void showdist() const // o/p the distance 
    { cout << feet << "\'-" << inches << '\"'; }
    operator float() const //conversion operator
    { // converts distance to meters
        float fracfeet = inches/12;
        fracfeet += static_cast<float>(feet);
        return fracfeet/MTF;
    }
};
int main()
{
    float mtrs;
    Distance dist1 = 2.35F; //meters to distance
    cout << "\ndist1 = "; dist1.showdist();
    mtrs = static_cast<float>(dist1); //casting distance to meters

    cout << "\ndist1 = " << mtrs << " meters\n";
    Distance dist2(5, 10.25);
    mtrs = dist2; //casting dist2 to meters
    cout << "\ndist2 = " << mtrs << " meters\n";


    Distance dist3; //new object dist3
    dist3 = mtrs; //here is the error 


//not converting meters to distance object
   

    cout<<"\ndist3 = ";dist3.showdist();
    return 0;
}

但代码显示错误:

在成员函数'Distance& Distance::operator=(const Distance&)'中:

错误:非静态 const 成员 'const float Distance::MTF',不能使用默认赋值运算符

不应该将 mtrs 转换为对象 dist3 吗?

为什么会出错?

【问题讨论】:

  • 请编辑您的问题以包含minimal reproducible example。显示的错误是由与您提供的源代码不同的源代码生成的。
  • 这与您遇到的问题无关,但与您的 Distance() 和 Distance(int ft, float in) 构造函数相比,您在 Distance(float meters) 构造函数中将 MTF 设置为不同的值。这就是当您可以使用 c++11 时,Slava 的以下回答很好的原因之一。
  • “英语距离”?在英格兰,我们从 1969 年就开始使用仪表。那是 47 年。将近半个世纪!

标签: c++ oop type-conversion


【解决方案1】:

你的错误实际上与该行有关

dist3 = mtrs;

不是

Distance dist3;

原因是Distance 有一个const 成员变量。因为是const,所以无法赋值,导致默认的复制赋值和移动赋值运算符被删除。

如果您想允许分配对象或编写自己的自定义分配函数,您将不得不重新考虑您的设计。

【讨论】:

  • 明显的解决方案是将该字段设为静态
  • @Slava 那或者只是一个全局常量。不确定哪种方式更好。
【解决方案2】:

你必须重写赋值运算符。代码应该如下所示

    #include <iostream>
using namespace std;

class Distance
{
private:
    const float MTF;
    int feet;
    float inches;
public:
    Distance() : feet(0), inches(0.0), MTF(3.280833F)
    { }
    Distance(float meters) : MTF(3.28033F)
    {
        float fltfeet = MTF * meters;
        feet = int(fltfeet);
        inches = 12*(fltfeet-feet);
    }
    Distance(int ft, float in) : feet(ft), inches(in), MTF(3.280833F)
    { }
    void getdist()
    {
        cout << "\nEnter feet: "; cin >> feet;
        cout << "Enter inches: "; cin >> inches;
    }
    void showdist() const
    { cout << feet << "\'-" << inches << '\"'; }
    operator float() const
    {
        float fracfeet = inches/12;
        fracfeet += static_cast<float>(feet);
        return fracfeet/MTF;
    }

    Distance& operator=(const Distance & otherD)
    {
        feet = otherD.feet;
        inches = otherD.inches;

        return *this;
    }
};
int main()
{
    float mtrs;
    Distance dist1 = 2.35F;
    cout << "\ndist1 = "; dist1.showdist();
    mtrs = static_cast<float>(dist1);

    cout << "\ndist1 = " << mtrs << " meters\n";
    Distance dist2(5, 10.25);
    mtrs = dist2;
    cout << "\ndist2 = " << mtrs << " meters\n";
    Distance dist3; //here is the error 
    dist3 = (Distance)mtrs ;


    //cout<<"\ndist3 = ";dist3.showdist();
    return 0;
}

正如另一位用户所说,您有一个“const”变量,因此您必须重写赋值运算符以满足您的要求。

【讨论】:

  • OP 不必这样做,这是可能的解决方案之一,而不是最好的解决方案。
  • operator= 的参数是否应该是浮点数,因为 mtrs 是浮点数?
  • 在 Visaul Studio 中尝试。我没有看到任何编译错误,一切都按预期工作。
  • 嗨,Jvinniec,我们的赋值运算符应该是通用的,所以使用类名。
  • Slava, constexpr 在 C++03 及以下版本中不存在。
【解决方案3】:

如果你想让类范围保持不变,你最好将你的类定义更改为:

class Distance
{
private:
    static constexpr float MTF = 3.280833F;
    int feet;
    float inches;
public:
    Distance() : feet(0), inches(0.0)
...

这将消除您遇到的错误并按您的预期工作。另外,您不必像在代码中那样多次定义该常量值。

注意:如果您不能使用 C++11,您可以将 MTF 设为全局常量(在 cpp 文件内的未命名命名空间中更好)或只是静态成员。无论哪种方式,它都会消除错误,您只需定义一次,这样就不容易出错。

【讨论】:

  • 请注意,您需要使用 c++11 标志(即std=c++11)进行编译才能使此解决方案有效。否则你会在编译时收到警告或错误。
【解决方案4】:

我认为错误出现在一行

dist3 = mtrs;

这里的问题是Distance没有一个赋值运算符接受float类型的参数,所以编译器尝试创建一个Distance类型的临时对象并用参数mtrs构造它;没关系,但下一步是将该临时值分配给dist3,编译器抱怨它无法将临时对象中MTF 的值分配给dist3 中MTF 的值因为MTF 是常量。

因为const,不能分配Distance 类型的对象。因此,例如,dist3 = dist2 也会失败。这可能不是您想要的,您可以通过添加一个忽略 MTF 值的赋值运算符来解决此问题。

【讨论】:

    【解决方案5】:

    发生错误,因为您无法在类中声明const。您应该在类之外定义 const 变量。您应该在此处将const float MTF 替换为float MTF。

    【讨论】:

      【解决方案6】:

      如其他答案所述,问题在于您已将 MTF 变量声明为 const。不过有一些方法可以解决这个问题。您已将变量设置为 const,因为它是一个常量,不应更改。相反,添加一个专用的Distance&amp; operator=(float feet) 方法,在该方法中,您在传入浮点值时实际设置英尺和英寸变量:

      class Distance
      {
      private:
          /* ... */
      public:
          /* ... */
          Distance& operator=(float feet)
          {
              // Set the feet and inches here from
              // the passed feet variable
              return *this;
          }
      };
      

      这应该可以解决从浮点数分配变量的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 2011-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多