неявное преобразование - PullRequest
1 голос
/ 08 марта 2011

В следующем примере автор сделал несколько комментариев по поводу неявного преобразования. Можете ли вы объяснить более подробно эти комментарии, которые мне не очень понятны? Спасибо.

class String{
  explicit String(int n);
  String(const char *p);
}
String  s1= ‘a’;     //error:  no implicit char->String conversion
void f(String);
String g( )
{
   f(10);           // error: no implicit int->String conversion
   return 10;   //  error:  no implicit int-> String conversion
}

Ответы [ 4 ]

2 голосов
/ 08 марта 2011

Класс String имеет два конструктора;один для построения String из int и один для построения String из константного указателя на char.Эти два конструктора, следовательно, также являются функциями преобразования, потому что они действительно преобразуют один тип в другой.Первый конструктор, однако, является явным конструктором.В то время как второй конструктор допускает неявное преобразование из указателя на char в String, первый конструктор требует явного запроса на преобразование.

Например:

String s;
s = 10;          // error: implicit conversion from int to String
s = String(10);  // ok: explicit conversion of int to String.

Первый комментарий об ошибке просто говорит, что не существует конструктора для преобразования char в String.Опять же, у нас есть только два конструктора: один для преобразования int, другой константный указатель в char.

Вторая ошибка говорит о передаче в качестве параметра int функции, которая требуетString.Это означает, что функция должна создать String из int неявно .Это не может быть сделано, потому что соответствующий конструктор является явным.Если бы вы построили String из int и затем передали бы эту String в функцию, все было бы хорошо.

Третья ошибка точно такая же, как и вторая, только здесь неявнаяпреобразование (которое завершается неудачно) заключается в возврате int, когда возвращаемое значение должно быть String.

. Интересно отметить, что код будет компилироваться, если целое число вваш код будет 0, а не 10. Причина в том, что 0 может быть неявно приведен к адресу (NULL-адресу), и это допустимое значение для конструктора, который принимает указатель.

String s;
s = 0;   // ok
s = '\0' // ok
1 голос
/ 08 марта 2011

Автор документирует случаи, когда компилятор выдаст вам ошибку, потому что либо нет преобразования, либо выбранное преобразование помечено explicit.Код может быть более понятным в случае, который на самом деле будет работать:

class String{
  explicit String(int n);
  String(const char *p);
};
String  s1= ‘a’;     //error:  no implicit char->String conversion
                     // There is a combo implicit/explicit one...
                     // char (implicit) -> int (explicit) -> String

void f(String);

String g( )
{
   f(10);       //  error: no implicit int->String conversion
                //  (the String(int n) constructor is marked explicit).

   f("fred");   //  not an error: uses the String(const char *) constructor
                //  for an implicit conversion.

   f(String(10)); // not an error, explicitly calls the String(int n)
                  // constructor.

   return 10;   //  error:  no implicit int-> String conversion
}
0 голосов
/ 23 декабря 2011

Как дополнительная информация.Прежде всего, почему мы должны беспокоиться о неявном преобразовании?Рассмотрим следующий сценарий.

#include <iostream>
#include <string>

using namespace std;

class Test
{
  public:
        Test ( int x);
        ~Test ();
        void print ();
        bool operator==(const Test &temp);
  private:
        int _x;
};

Test::Test (int x)
{
  _x = x;
}

Test::~Test ()
{
}

void Test::print ()
{
 cout <<"_x : "<<_x<<endl;
}

bool Test::operator==(const Test & temp)
{
    cout <<"Comparing "<<_x <<" With "<<temp._x<<endl;
    if (_x == temp._x) return 1;
    else
       return 0;
}

int main (int argc, char ** argv)
{
   Test t1(10); //OK
   Test t2 = 10; // We intented
   t1.print ();  /* Excellent */
   t2.print ();

   /* What we do not intend is this : silent Conversion from int to Object */
   /* Hey man i forgot to mention t2, but mentioned '2' instead. */

   if ( t1 == 2 )
    cout <<"TRUE"<<endl;
   else
    cout <<"FALSE"<<endl;
}

Он все еще компилируется и преобразует целое число '2' в Тестовый объект, который не был моим намерением, но сравнить t1 и t2Использование «явного» ключевого слова перед конструктором с одним аргументом позволяет избежать такого тихого преобразования.Надеюсь, это поможет !!! ..

explict test (int x);  
0 голосов
/ 08 марта 2011

В комментариях в основном говорится, что компилятор не может узнать, как преобразовать в / из тип данных String.

См .: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr383.htm

Также: http://www.glenmccl.com/tip_023.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...