【问题标题】:Specify "return type" for class object为类对象指定“返回类型”
【发布时间】:2013-06-09 04:08:58
【问题描述】:

我有以下类,它应该代表一个 8 位有符号字符。

class S8
{
private:
    signed char val;
public:
    S8 & operator=(const signed char other)
    {
        if ((void*)this != (void*)&other)
        {
            val = other;
        }
        return *this;
    }
    operator signed char() {signed char i; i = (signed char) val; return i;}
    void write (OutputArray & w)
    {
        /* This function is the whole purpose of this class, but not this question */
    }
};

但是,当我将负数分配给它的一个对象时,

S8 s;
char c;

s = -4;
c = -4;

printf("Results: %d, %s\n",s,c);

我从 printf 中得到“结果:252,-4”。有什么方法可以修改类,这样这样的情况会看到有符号字符的行为,而不是我得到的无符号字符行为?

谢谢!

【问题讨论】:

  • 未定义的行为:不使用printf的充分理由。
  • 你的重载赋值运算符真的很奇怪。您的地址检查永远不会是真的(无论如何请参阅复制交换),您甚至不需要重载它。只需有一个来自signed char 的转换构造函数。您的转换运算符也可以是 return val;
  • printf 只是一个健全的检查,以确保我没有丢失标志。我想我会看到负数,而不是二进制补码。很高兴知道只是我不知道如何使用 printf,谢谢!我将研究赋值运算符...它是来自不同 SO 问题的复制/粘贴,我没有考虑太多
  • 为什么要为签名字符创建一个类?这似乎毫无意义。
  • 对于 %s 格式,您必须传递 const char* 指向以 0 结尾的字符串。对于 char,您必须使用 %c。这样你就有了UB。并且通过非 POD 作为您的课程也是 UB

标签: c++


【解决方案1】:

您想要的是从有符号字符到 S8 对象的隐式转换;这是通过非默认复制构造函数完成的。如果定义了采用有符号字符的复制构造函数,则编译器将使用它进行隐式转换(假设复制构造函数未定义为“显式”)。因此,对于您的示例:

class S8
{
private:
    signed char val;
public:
    //default constructor
    S8() : val(0) {}

    //default copy-constructor
    S8(const S8& rhs) : val(rhs.val) {}

    //allow implicit conversions (non-default copy constructor)
    S8(const signed char rhs) : val(rhs) {}

    //allow implicit conversions
    operator signed char() { return val; }
};    

int main()
{
  S8 s;
  signed char c;

  s = -4;
  c = -4;

  std::cout << (int) s << std::endl;
  std::cout << (int) c << std::endl;

  return 0;
}

【讨论】:

  • 非常感谢!我不知道隐式转换,这使得我很难找到关于:) 的信息。
【解决方案2】:

您的代码完全没有意义,而您遇到的行为完全是任意的,因为 printf 不能以这种方式使用。 (您是否至少在编译器中打开了警告?很多人会标记您的错误!)

除此之外,您的输入和输出转换器做了您所追求的,只是措辞很糟糕。在 op= 中,rhs 是 char,它不可能在你的类的同一个地址上,所以你可以继续存储它。

隐式转换操作也无需大惊小怪,只需返回成员即可。

你为什么需要这个还不清楚,可能你应该阅读隐式转换和自定义 op= 的东西。由于它存在各种危险,并且只能由那些清楚知道何时应用转换的人使用,因此客户端代码非常欢迎这种情况,并且客户端代码不太可能在转换存在的情况下陷入困境。

【讨论】:

  • 代码确实有意义。我需要一个有符号的 char 类型,它有一个与之关联的 write() 函数......并且在一个类中将它关联在一起看起来比一个独立的函数更漂亮。我不知道隐式转换,这是我需要指导的主题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 2018-10-19
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多