1

我有以下类,它应该代表一个 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”。有没有办法修改类,这样的情况下会看到有符号字符的行为,而不是我得到的无符号字符行为?

谢谢!

4

2 回答 2

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;
}
于 2013-06-09T07:19:31.670 回答
0

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

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

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

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

于 2013-06-09T11:09:37.173 回答