2013-06-09 6 views
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); 

Я получаю "Результаты: 252, -4" от Printf. Есть ли способ изменить класс таким образом, чтобы такие случаи видели поведение подписанного символа, а не поведение без знака, которое я получаю?

Спасибо!

+3

Неопределенное поведение: хорошая причина не использовать 'printf'. – chris

+3

И ваш перегруженный оператор присваивания действительно странный. Ваша проверка адреса никогда не будет правдой (см. «Копирование-обмен»), и вам даже не нужно ее перегружать. Просто создайте конструктор преобразования из 'signed char'. Ваш оператор преобразования мог бы просто «вернуть val». – chris

+0

Печать была просто проверкой, чтобы я не потерял знак. Я решил, что увижу отрицательное число, а не дополнение к нему. Приятно было знать, что это был только я, не зная, как использовать printf, спасибо! Я рассмотрю оператор присваивания ... это была копия/вставка из другого вопроса SO, и я не задумывался о нем – SVC

ответ

1

Что вы хотите - это неявное преобразование из подписанного символа в объект S8; и это выполняется с помощью нестандартного конструктора-копии. Если конструктор-копир, принимающий подписанный символ, определен, то компиляторы будут использовать это для неявных преобразований (предполагая, что copy-constructor не определен как «явный»). Так, для примера:

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; 
} 
+0

Большое спасибо!Я не знал о неявных конверсиях, что затрудняло поиск информации о :) теперь я знаю. – SVC

0

Ваш код не имеет смысла, в то время как поведение, которое вы испытываете, совершенно произвольно, как Printf не должны использоваться таким образом. (вы хотя бы включили предупреждения в своем компиляторе? Многие отметят вашу ошибку!)

Кроме того, ваши входные и выходные преобразователи сделали то, что вам нужно, просто сформулировали плохо. В op = rhs есть char, он не может быть на одном и том же адресе вашего класса, поэтому вы можете просто продолжить его и сохранить.

Неявное преобразование op также не требует никакой суеты, просто возвращает член.

Зачем вам это нужно, это неясно, возможно, вам следует прочитать о неявных преобразованиях и пользовательских операциях op =. Поскольку он содержит все виды опасности и должен использоваться только теми, кто четко знает, когда будут применяться преобразования, что клиентский код таков, чтобы приветствовать это, а клиентский код вряд ли попадет в яму с присутствующим преобразованием.

+0

Код имеет смысл. Мне нужен подписанный тип char, у которого есть связанная с ним функция write() ... и связанная с ним связь в классе выглядит красивее, чем отдельная функция. Я не знал о неявных конверсиях, и это была тема, в которой я нуждался. – SVC

Смежные вопросы