Ссылка и NULL
От: Аноним  
Дата: 04.05.08 13:53
Оценка: :)))
Привет!

Почему в качестве значения ссылки можно передать NULL, но никак нельзя проверить, что NULL передан, и как предотвратить возможность передачи NULL?

Пример компилируется GCC 3.4.5, при выполнении, естественно, runtime error.

#include <iostream>

using namespace std;

class foo {
public:
  void bar(const string &str) {
//      if (str != NULL) <-- как проверить ссылку на NULL???
        cout << str << endl;
  }
};

int main() {
    foo f;
    f.bar(NULL);
    return 0;
};
Re: Ссылка и NULL
От: remark Россия http://www.1024cores.net/
Дата: 04.05.08 13:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет!


А>Почему в качестве значения ссылки можно передать NULL, но никак нельзя проверить, что NULL передан, и как предотвратить возможность передачи NULL?


А>Пример компилируется GCC 3.4.5, при выполнении, естественно, runtime error.



Попробуй пошагово продебажить программу и погляди где именно падает.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Ссылка и NULL
От: alzt  
Дата: 04.05.08 14:11
Оценка:
Здравствуйте, Аноним, Вы писали:

Всё смешалось в доме Облонских.
Re: Ссылка и NULL
От: AKh  
Дата: 04.05.08 14:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему в качестве значения ссылки можно передать NULL, но никак нельзя проверить, что NULL передан, и как предотвратить возможность передачи NULL?


В качестве значения ссылки std::string нельзя передать NULL — несоответствие типов.
Проверить расположение данных по ссылке на NULL можно — operator&()
Re[2]: Ссылка и NULL
От: Аноним  
Дата: 04.05.08 14:16
Оценка:
A>Всё смешалось в доме Облонских.

хватит глумиться

ту Аноним:
компилятор НУЛЛ пытаются к std::string неявно преобразовать и падает в конструкторе std::string(const char*), когда туда 0 приходит
Re[3]: Ссылка и NULL
От: Аноним  
Дата: 04.05.08 14:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>ту Аноним:

А>компилятор НУЛЛ пытаются к std::string неявно преобразовать и падает в конструкторе std::string(const char*), когда туда 0 приходит

Спасибо, а то я без отладчика работаю
Re: Ссылка и NULL
От: Кодт Россия  
Дата: 04.05.08 15:55
Оценка: 1 (1) +2
Здравствуйте, <Аноним>, Вы писали:

А>Почему в качестве значения ссылки можно передать NULL, но никак нельзя проверить, что NULL передан, и как предотвратить возможность передачи NULL?


Ты немножко не врубился.

Во-первых.

f.bar(NULL) <==> f.bar(string(NULL)) — смотрим на сигнатуры конструкторов std::string...
Точно! Есть конструктор string::string(const char* str), принимающий на вход сишную строку. Ненулевую! Вот поэтому-то оно и падает.
А до передачи ссылки на сконструированный объект дело не доходит.
Кстати, string::operator!= тоже имеет сигнатуру (const char*), тоже принимающую ненулевую строку. Так что в этом месте оно тоже рухнет.

Во-вторых.

Срочно забудь про ссылки из шарпа, бейсика и т.п.
В С++ указатель и ссылка — это совершенно не одно и то же, хотя зачастую ссылка реализуется через указатель.
Тут я даже побоюсь делать развёрнутый комментарий, поскольку объём его потянет на главу учебника, как минимум. Так что берёшь хорошую книжку по С++ и вперёд.
Основное отличие: ссылки не бывают нулевыми. Получить нулевую ссылку можно только посредством неопределённого поведения (разыменовав нулевой указатель, либо нахимичив со смещением базы, либо грамотно расстреляв память).
Если же ты хочешь передавать отсылку к объекту-либо-его-отсутствию, то так и передавай указатель. Если хочешь передавать копию объекта или его отсутствие, и не боишься мегакрутого программирования — то смотри boost::optional.

А в данном конкретном случае тебе нужна не нулевая ссылка, а пустая строка. То есть, "".
Так и пиши
void foo::bar(const string& str)
{
    if(str != "") // или !str.empty(), или str != string()
        cout << str << endl;
}

int main()
{
    foo f;
    f.bar(""); // или f.bar(string());
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: Ссылка и NULL
От: igna Россия  
Дата: 04.05.08 17:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему в качестве значения ссылки можно передать NULL, но никак нельзя проверить, что NULL передан, и как предотвратить возможность передачи NULL?


Вот так (иногда) можно:

#include <iostream>
#include <string>

using namespace std;

class foo {
public:
    void bar(const string &str) {
        if (&str != NULL)
            cout << str << endl;
    }
};

int main() {
    foo f;
    f.bar(*static_cast<const string*>(NULL));
    return 0;
};


Но не нужно. Стандарт не разрешает иметь в программе "нулевую ссылку", то есть никакой гарантии, что такое будет работать в будущем, хотя возможно на конкретной платформе с конкретным компилятором оно работает сейчас. В этом случае используй константный указатель, даже если никакие другие возможности указателя тебе не нужны:

#include <iostream>
#include <string>

using namespace std;

class foo {
public:
    void bar(const string * const pstr) {
        if (pstr != NULL)
            cout << *pstr << endl;
    }
};

int main() {
    foo f;
    f.bar(NULL);
    return 0;
};
Re[4]: Ссылка и NULL
От: Аноним  
Дата: 05.05.08 06:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Спасибо, а то я без отладчика работаю


настолько суров?
Re[3]: Ссылка и NULL
От: alzt  
Дата: 05.05.08 09:56
Оценка:
Здравствуйте, Аноним, Вы писали:

A>>Всё смешалось в доме Облонских.


А>хватит глумиться


А>ту Аноним:

А>компилятор НУЛЛ пытаются к std::string неявно преобразовать и падает в конструкторе std::string(const char*), когда туда 0 приходит

Из примера не совсем понятно, что человек хочет сделать.
У меня возникла мысль, что он путает ссылки и указатели. И в примере хочет использовать
void bar(const string* str);

куда будет передавать некоторую строчку, либо 0, если параметр не используется.

Возможно, наоборот — пустая строка должна свидетельствовать о том, что параметр не используется.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.