Что такое bool в C ++? - PullRequest
       3

Что такое bool в C ++?

4 голосов
/ 17 июля 2010

Я наткнулся на очень интересный код, который заставляет меня задуматься о том, что такое bool. Я всегда считал, что это примитивный тип, например, int, char или long. Но сегодня я увидел нечто, похожее на это:

void boolPtrTest()
{
    bool thisBool = true;

    boolPtrHere(thisBool);

    printf("thisBool is %s\n", thisBool ? "true" : "false");
}

void boolPtrHere(bool& theBool)
{
    theBool = false; // uhh, dereferencing anyone?
}

И этот код запускается - без ошибок - и выводит «thisBool is false»!

Чтобы сделать это еще более странным, я запустил следующий код:

bool myBool = new bool();

... и код работал нормально!

Перед тем как пойти и понизить голос за вопрос "нубиш"

Вот мой вопрос: что это bool? Определяется ли он на основе реализации? Из приведенных выше доказательств я бы сказал, что это класс. С практической точки зрения (не принимая во внимание вышесказанное), было бы также целесообразно определить bool как typedef для int / char или иметь его # define'd. Но как узнать, что это такое (что повлияет на то, как вы относитесь к этому)?

РЕДАКТИРОВАТЬ: Я думал, что я добавлю, что я работаю в VS 2008.

Ответы [ 8 ]

21 голосов
/ 17 июля 2010

Я просто не вижу описанную вами "странность".

Вы объявляете bool, инициализированный как true.Вызывая функцию и передавая ее по ссылке, вы изменяете ее значение на false.

Затем вы распечатываете значение, и оно работает.В чем проблема?Точнее, что является свидетельством того, что происходит что-то странное?

Поскольку вы хотите узнать подробности, bool, вероятно, является либо байтом (char), либо int.Когда вы присваиваете ему значение true / false, он получает значения 0 или 1. (используйте sizeof и printf("%d") для его проверки).

Я подозреваю, что реальная проблема в том, что вы не понимаете передача по ссылке из boolPtrHere.Вы не передаете указатель на bool.Вы передаете фактическое значение по ссылке в памяти.(воспринимайте это как указатель, который вам не нужно отменять).

13 голосов
/ 17 июля 2010
void boolPtrHere(bool& theBool)
{
    theBool = false; // uhh, dereferencing anyone?
}

В этом коде нет ничего плохого. Bool взят по ссылке . Разыменование не требуется.

bool myBool = new bool();

new возвращает адрес, который преобразуется в true, поскольку он никогда не возвращает ненулевое значение. Это обычное преобразование, особенно в коде C:

int* my_int = malloc(10 * sizeof(int));
if (!my_int) // my_int is converted to bool
    memory_error();
9 голосов
/ 17 июля 2010

bool является фундаментальным типом;true и false - это только два значения, которые может иметь инициализированный объект типа bool.

Ваша функция boolPtrHere() не принимает указатель на bool (который будет bool*);требуется ссылка на bool.Он работает как любая другая ссылка в C ++.

Что касается вашего последнего примера:

bool myBool = new bool();

В C ++ указатель неявно преобразуется в bool.Новое выражение возвращает указатель на динамически размещенный объект bool.Этот указатель затем преобразуется в bool и сохраняется в myBool.Если указатель нулевой, то myBool будет ложным;в противном случае это будет истина (поскольку new никогда не возвращает ноль, myBool всегда будет истиной в этом случае).

4 голосов
/ 17 июля 2010

Bool - это четко определенный примитивный целочисленный тип, такой же как int, char и т. Д. Он также имеет математические преобразования в другие целочисленные типы, что иногда может сбивать людей с толку, но я не думаю, что это Ваше текущее замешательство.

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

Что касается второго фрагмента кода, это немного сложно. это на самом деле утечка памяти, и если мы напишем ее по-другому, должно стать более понятно, что она делает:

 bool myBool = (new bool) != 0 ? true : false;

Исходя из этого, вы можете видеть, что это делает, выделяет bool из кучи, затем сравнивает результат с NULL / 0 и использует результат этого сравнения для присваивания логическому значению. Обратите внимание, что значение, первоначально выделенное из кучи, просочилось. Я немного удивлен, что это не генерирует для вас ошибку компилятора, я подозреваю, что на некоторых компиляторах это будет.

1 голос
/ 17 июля 2010

Ссылки не должны быть разыменованы. Указатели делают.

0 голосов
/ 17 июля 2010

Один очень маленький сюрприз о bool - sizeof(bool) >= 1. Для bool требуется полный байт памяти. Это сделано для того, чтобы они могли иметь уникальный адрес и на них указывать, как в функции boolPtrHere.

0 голосов
/ 17 июля 2010

Я всегда считал это примитивный тип, например, int или char или длинный.

Кажется, вы смотрите на C ++ с точки зрения Java. В Java примитивные типы всегда передаются по значению, а другие всегда являются ссылками.

C ++ отличается. Любой тип может быть ссылкой, если объявлен таким образом. Вы также можете объявить int &x или int *x, так что в bool нет ничего странного.

0 голосов
/ 17 июля 2010

Думайте об этом так:

typedef enum { false=0, true=1 } bool;
...