C++ 请注明“;返回类型";对于类对象

C++ 请注明“;返回类型";对于类对象,c++,C++,我有下面的类,它应该代表一个8位有符号字符 class S8 { private: signed char val; public: S8 & operator=(const signed char other) { if ((void*)this != (void*)&other) { val = other; } return *this; } op

我有下面的类,它应该代表一个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”。是否有任何方法可以修改该类,使类似这样的情况下可以看到有符号字符的行为,而不是我得到的无符号字符的行为


谢谢

您需要的是从有符号字符到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;
}
S8级
{
私人:
签名字符val;
公众:
//默认构造函数
S8():val(0){}
//默认副本构造函数
S8(常数S8和rhs):val(rhs.val){}
//允许隐式转换(非默认复制构造函数)
S8(常数符号字符rhs):val(rhs){}
//允许隐式转换
运算符签名字符(){return val;}
};    
int main()
{
S8-s;
签名字符c;
s=-4;
c=-4;

std::cout您想要的是从有符号字符到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;
}
S8级
{
私人:
签名字符val;
公众:
//默认构造函数
S8():val(0){}
//默认副本构造函数
S8(常数S8和rhs):val(rhs.val){}
//允许隐式转换(非默认复制构造函数)
S8(常数符号字符rhs):val(rhs){}
//允许隐式转换
运算符签名字符(){return val;}
};    
int main()
{
S8-s;
签名字符c;
s=-4;
c=-4;

std::cout您的代码毫无意义,而您所经历的行为完全是任意的,因为printf不能以这种方式使用。(您是否至少在编译器中打开了警告?许多人会标记您的错误!)

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

隐式转换op也不需要麻烦,只需返回成员即可


您为什么需要它还不清楚,可能您应该仔细阅读隐式转换和自定义op=stuff。因为它包含各种危险,并且只应该由那些清楚知道转换将在何时应用的人使用,客户机代码对此表示欢迎,并且客户机代码不太可能在存在转换的情况下落入陷阱。

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

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

隐式转换op也不需要麻烦,只需返回成员即可


您为什么需要它还不清楚,可能您应该仔细阅读隐式转换和自定义op=stuff。因为它包含各种危险,并且只应该由那些清楚知道转换何时应用的人使用,客户机代码非常欢迎这种情况,并且客户机代码不太可能在存在转换的情况下落入陷阱。

Und定义的行为:不使用
printf
的一个很好的理由。而且您的重载赋值运算符非常奇怪。您的地址检查永远不会为真(请参阅复制交换),您甚至不需要重载它。只要从
带符号字符
中获得一个转换构造函数即可。您的转换运算符也可以
返回val;
。printf只是一个健全的检查,以确保我没有丢失符号。我想我会看到负数,而不是2的补码。很高兴知道这只是我而不是k现在知道如何使用printf了,谢谢!我将研究赋值运算符…这是一个来自不同SO问题的复制/粘贴,我没有仔细考虑为什么要为签名字符创建一个类?这似乎毫无意义。对于%s格式,您必须传递指向以0结尾的字符串的const char*。对于字符,您必须使用%c。这样您就可以UB。并且在类中传递非POD是未定义的行为:不使用
printf
的一个很好的理由。重载赋值运算符非常奇怪。您的地址检查将永远不会为真(无论如何请参阅复制交换),您甚至不需要重载它。只要从
带符号字符
中获得一个转换构造函数即可。您的转换运算符也可以
返回val;
。printf只是一个健全的检查,以确保我没有丢失符号。我想我会看到负数,而不是2的补码。很高兴知道这只是我而不是k现在知道如何使用printf了,谢谢!我将研究赋值运算符…这是一个来自不同SO问题的复制/粘贴,我没有仔细考虑为什么要为签名字符创建一个类?这似乎毫无意义。对于%s格式,您必须传递指向以0结尾的字符串的const char*。对于字符,您必须使用%c。这样您就可以我不知道隐式转换,这让我很难找到:)现在我知道了。非常感谢!我不知道隐式转换,这让我很难找到:)现在我知道了。代码确实有意义。我需要一个有符号的字符类型that有一个与之相关联的write()函数……在一个类中将它关联在一起看起来比独立函数更漂亮