printПерегрузка функций и операций

printОперация преобразования

Операция преобразования определяется как метод с заголовком вида:
operator другой тип();
и используется при необходимости для преобразования из определяемого типа в другой тип.

Не следует определять одновременно операцию преобразования и обратный к ней конструктор-преобразователь.
class String {
  int len;
  char * str;
public:
  String(const char *s=""); // конструктор-преобразователь
  String& operator=(const String&); // операция присваивания
  operator const char *() const { return str; } // операция преобразования
  friend bool operator==(const String &,const String &);
  ...
};
int main()
{
  int x;
  String fmt, txt("ABC");
  fmt="%d\n"; // Ok, неявное преобразование const char * -> String
  printf(fmt,x); // Ok, неявное преобразование String -> const char *
  if(fmt==txt) // Ok, преобразований не нужно
    ...
  if(fmt=="ABC") // Ошибка, какое преобразование выполнять?
      // можно сравнить два String, а можно два char *
    ...
}
В таких случаях не определяют операцию преобразования, вместо неё делают обычный метод:
class String {
  int len;
  char * str;
public:
  String(const char *s=""); // конструктор-преобразователь
  String& operator=(const String&); // операция присваивания
  const char * c_str() const { return str; } // метод вместо операции преобразования
  friend bool operator==(const String &,const String &);
  ...
};
int main()
{
  int x;
  String fmt, txt("ABC");
  fmt="%d\n"; // Ok, неявное преобразование const char * -> String
  printf(fmt.c_str(),x); // Ok, нужно явно вызывать метод
  if(fmt==txt) // Ok, преобразований не нужно
    ...
  if(fmt=="ABC") // Ok, неявное преобразование const char * -> String
    ...
}
Альтернативным вариантом исправления проблемы является указание explicit у операций преобразования.

class String {
  int len; char * str;
public:
  String(const char *s=""); //конструктор-преобр-тель
  explicit operator const char *() const { return str; }
  ...
};
int main() {
  String fmt, txt("ABC"); int x=1;
  fmt="%d\n"; // Ok, неявное const char * -> String
  printf(fmt,x); // Ошибка
  printf((const char *)fmt,x); // Ok
  if(fmt==txt) // Ok, преобразований не нужно
  if(fmt=="ABC") // Ok, неявное const char * -> String

loading