NULL вместо объекта класса
От: Sr.Melifaro Россия www.wcrow.ru
Дата: 05.12.07 13:16
Оценка:
Приветствую, уважаемые господа!

Интересует следующий вопрос:
Есть массив объектов класса [3][3][3]. Некоторые из них проинициализированы значениями. Остальные создаются дефолтовым конструктором. Можно ли вместо проверки на то, был ли объект массива создан по дефолту использовать проверку на NULL и не создавать дефолтовых объектов вообще? Тоесть хранить NULL вместо них?
Re: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 13:22
Оценка: 2 (1)
Здравствуйте, Sr.Melifaro, Вы писали:

SM>Приветствую, уважаемые господа!


SM>Интересует следующий вопрос:

SM>Есть массив объектов класса [3][3][3]. Некоторые из них проинициализированы значениями. Остальные создаются дефолтовым конструктором. Можно ли вместо проверки на то, был ли объект массива создан по дефолту использовать проверку на NULL и не создавать дефолтовых объектов вообще? Тоесть хранить NULL вместо них?

Конечно нет. NULL — это нулевой указатель.
Впрочем, если ты перегрузищь operator == () для соответствующих типов, тогда можно
Любите книгу — источник знаний (с) М.Горький
Re: NULL вместо объекта класса
От: biomorph Россия  
Дата: 05.12.07 13:23
Оценка:
Здравствуйте, Sr.Melifaro, Вы писали:

SM>Можно ли вместо проверки на то, был ли объект массива создан по дефолту использовать проверку на NULL и не создавать дефолтовых объектов вообще? Тоесть хранить NULL вместо них?


Можно попробовать хранить указатели, а не сами объекты. Тогда ненужные объекты можно не создавать и хранить там NULL.
Re[2]: NULL вместо объекта класса
От: Sr.Melifaro Россия www.wcrow.ru
Дата: 05.12.07 13:25
Оценка:
Здравствуйте, Bell, Вы писали:

B>Впрочем, если ты перегрузищь operator == () для соответствующих типов, тогда можно


Точно! Именно то что нужно Голова не варит совсэм
Re[3]: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 13:28
Оценка:
Здравствуйте, Sr.Melifaro, Вы писали:

B>>Впрочем, если ты перегрузищь operator == () для соответствующих типов, тогда можно


SM>Точно! Именно то что нужно Голова не варит совсэм


Вообще-то я пытался так пошутить
Не думаю, что это хорошее решение. Уж лучше определить в классе метод IsNull, или воспользоваться советом biomorph, и хранить в массиве (умные)указатели...
Любите книгу — источник знаний (с) М.Горький
Re[4]: NULL вместо объекта класса
От: Sr.Melifaro Россия www.wcrow.ru
Дата: 05.12.07 14:39
Оценка:
Здравствуйте, Bell, Вы писали:

B>Вообще-то я пытался так пошутить

B>Не думаю, что это хорошее решение. Уж лучше определить в классе метод IsNull, или воспользоваться советом biomorph, и хранить в массиве (умные)указатели...

указатели сильно усложнят процесс создания и изменения этого массива.
сейчас у меня реализовано следующим образом:

В массиве хранятся объекты следующего вида:
class myPoint
{
     int m_x;
     int m_y;
     int m_z;

public:
     myPoint()
     {
          this->m_x = -1;
          this->m_y = -1;
          this->m_z = -1;
     }

     bool operator == (int a)
     {
          return m_x == a && m_y == a && m_z == a;
     }
};

Данный вариант меня устраивает. Но хотелось реализовать скажем такую конструкцию:
myPoint a[3][3][3] = { ... };
if (a[i][j][k])
{
     ...
}
Re[5]: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 14:54
Оценка: :)
Здравствуйте, Sr.Melifaro, Вы писали:

...

SM>Данный вариант меня устраивает. Но хотелось реализовать скажем такую конструкцию:

SM>
SM>myPoint a[3][3][3] = { ... };
SM>if (a[i][j][k])
SM>{
SM>     ...
SM>}
SM>


Значит тебе нужен operator bool, а чтобы уж быть правильным до конца, то operator "safe bool":

class myPoint
{
     int m_x;
     int m_y;
     int m_z;

     void safe_bool_fn() const;
     typedef void (myPoint::*safe_bool)() const;
public:
     myPoint()
     {
          this->m_x = -1;
          this->m_y = -1;
          this->m_z = -1;
     }

     bool operator == (int a)
     {
          return m_x == a && m_y == a && m_z == a;
     }

     operator safe_bool () const { return (-1 == m_x && -1 == m_y && -1 == m_z) ? 0 : &myPoint::safe_bool_fn; }};

int main()
{
   myPoint a[3][3][3] = { };
   if (a[0][0][0])
      return 1;

   return 0;
}


Подробнее про идиому "Safe Bool" можно почитать, например, здесь.
Любите книгу — источник знаний (с) М.Горький
Re[6]: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 14:56
Оценка:
Здравствуйте, Bell, Вы писали:


B>
B>class myPoint
B>{
B>     int m_x;
B>     int m_y;
B>     int m_z;

B>     void safe_bool_fn() const;
B>     typedef void (myPoint::*safe_bool)() const;
B>public:
B>     myPoint()
B>     {
          this->>m_x = -1;
          this->>m_y = -1;
          this->>m_z = -1;
B>     }

B>     bool operator == (int a)
B>     {
B>          return m_x == a && m_y == a && m_z == a;
B>     }

B>     operator safe_bool () const { return (-1 == m_x && -1 == m_y && -1 == m_z) ? 0 : &myPoint::safe_bool_fn; }
};

Лучше вот так:

[ccode]
...
     bool operator == (int a) const
     {
          return m_x == a && m_y == a && m_z == a;
     }

     operator safe_bool () const { return (*this == -1) ? 0 : &myPoint::safe_bool_fn; }
...
Любите книгу — источник знаний (с) М.Горький
Re[6]: NULL вместо объекта класса
От: Sr.Melifaro Россия www.wcrow.ru
Дата: 05.12.07 15:06
Оценка:
Здравствуйте, Bell, Вы писали:

B>Подробнее про идиому "Safe Bool" можно почитать, например, здесь.


Хм... Интересное решение... почитаю.
Спасибо!
Re[6]: NULL вместо объекта класса
От: Erop Россия  
Дата: 05.12.07 15:15
Оценка:
Здравствуйте, Bell, Вы писали:

B>Подробнее про идиому "Safe Bool" можно почитать, например, здесь.



А зачем таки сложности, для такой простой задачи?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: NULL вместо объекта класса
От: Erop Россия  
Дата: 05.12.07 15:17
Оценка:
Здравствуйте, Sr.Melifaro, Вы писали:

SM>Есть массив объектов класса [3][3][3]. Некоторые из них проинициализированы значениями. Остальные создаются дефолтовым конструктором. Можно ли вместо проверки на то, был ли объект массива создан по дефолту использовать проверку на NULL и не создавать дефолтовых объектов вообще? Тоесть хранить NULL вместо них?


Не совсем понятен вопрос.
1) Не совсем понятно что значит "хранить NULL вместо объекта"
2) Не совсем понятно насколько твой массив разреженный.

Возможно тебе было бы удобнее хранить hash_map из троек индексов в элементы твоего массива, а если эл-та нет, то возвращать дефолтный объект...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 15:20
Оценка: :)
Здравствуйте, Erop, Вы писали:

B>>Подробнее про идиому "Safe Bool" можно почитать, например, здесь.


E>А зачем таки сложности, для такой простой задачи?


Ну так в той статье ведь написано
ну и

чтобы уж быть правильным до конца

Любите книгу — источник знаний (с) М.Горький
Re[6]: NULL вместо объекта класса
От: Eternal  
Дата: 05.12.07 15:29
Оценка: +1
Здравствуйте, Bell, Вы писали:

B>Значит тебе нужен operator bool, а чтобы уж быть правильным до конца, то operator "safe bool":


Забыл шаблоны и буст прикрутить.
И нахрена весь этот огород? Метода IsValid достаточно (лучще его конечно более подходяшим именем назвать).
Re[7]: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 15:42
Оценка: +1 :)
Здравствуйте, Eternal, Вы писали:

E>Здравствуйте, Bell, Вы писали:


B>>Значит тебе нужен operator bool, а чтобы уж быть правильным до конца, то operator "safe bool":


E>Забыл шаблоны и буст прикрутить.

Мне, если честно, не совсем понятен шум вокруг достаточно простого и распространенного приема

E>И нахрена весь этот огород? Метода IsValid достаточно (лучще его конечно более подходяшим именем назвать).

Этот "огород" был предложен в ответ на вопрос

Данный вариант меня устраивает. Но хотелось реализовать скажем такую конструкцию:

myPoint a[3][3][3] = { ... };
if (a[i][j][k])
{
     ...
}


ЗЫ
На вропрос "зачем" можно себе ответить, сходив по предложенной мной ссылке.
Любите книгу — источник знаний (с) М.Горький
Re[5]: NULL вместо объекта класса
От: Кодт Россия  
Дата: 05.12.07 15:55
Оценка:
Здравствуйте, Sr.Melifaro, Вы писали:

SM>В массиве хранятся объекты следующего вида:

SM>
SM>class myPoint
SM>{
SM>     int m_x;
SM>     int m_y;
SM>     int m_z;

SM>public:
SM>     myPoint()
SM>     {
          this->>m_x = -1;
          this->>m_y = -1;
          this->>m_z = -1;
SM>     }

SM>     bool operator == (int a)
SM>     {
SM>          return m_x == a && m_y == a && m_z == a;
SM>     }
SM>};
SM>

Это в том случае, если существует дефолтное значение (в смысле обломное, а не просто умолчательное).
Например, у плавающих чисел это NaN, у указателей NULL, у дескрипторов -1.
Тогда можно проверку инициализированности не-дефолтом свести к проверке синдрома — как это делаешь ты, утверждая, что (-1,-1,-1) это особая точка, выколотая из пространства допустимых значений.

Кстати, проверку можно было делать по-человечески
class mypoint
{
    .....
public:
    bool isNothing() const // не забываем про константность!
    {
        return m_x==-1 && m_y==-1 && m_z==-1;
    }
    
    operator safe_bool() const { return to_safe_bool(!isNothing()); }
};

А то ты нахаляву получил оператор сравнения с векторами (t,t,t), который к тому же понижает ошибкоустойчивость.

Если же синдрома нет, то придётся вводить дополнительные флаги.
class mypoint
{
    int m_x, m_y, m_z;
    bool m_initialized;
public:
    mypoint() : m_initialized(false) {}
    mypoint(int x, int y, int z) : m_x(x), m_y(y), m_z(z), m_initialized(true) {}
    .....
};

Или же, действительно, пойти на сокращение пространства допустимых значений.
Но я бы тогда предпочёл выколоть не -1, а -INT_MAX. Всё-таки шанс, что потребуется именно оно, — гораздо меньше.

А ещё можно предложить такой вариант:
class mypoint
{
public:
    mypoint() {} // забивает на инициализацию
    mypoint(int x, int y, int z);
    .....

    friend operator ==(mypoint const& a, mypoint const& b) { return a.m_x==b.m_x && a.m_y==b.m_y && a.m_z==b.m_z; }
    friend operator !=(mypoint const& a, mypoint const& b) { return !(a==b); }
};

template<int X0, int Y0, int Z0>
class mypoint_z : public mypoint
{
public:
    mypoint_z() : mypoint(X0,Y0,Z0) {}
    mypoint_z(int x, int y, int z) : mypoint(x,y,z) {}
    
    operator safe_bool() const { return to_safe_bool( *this != mypoint_z() ); }
};
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[6]: NULL вместо объекта класса
От: Bell Россия  
Дата: 05.12.07 16:00
Оценка: :)
Здравствуйте, Кодт, Вы писали:

...

К>template<int X0, int Y0, int Z0>
К>class mypoint_z : public mypoint


Ну чтоже, шаблоны появились.
С нетерпением ждем комментариев от Erop и Eternal.
Любите книгу — источник знаний (с) М.Горький
Re[7]: NULL вместо объекта класса
От: Erop Россия  
Дата: 05.12.07 16:17
Оценка: :)
Здравствуйте, Bell, Вы писали:

B>Ну чтоже, шаблоны появились.

B>С нетерпением ждем комментариев от Erop и Eternal.

Ну Boost'а-то пока что нет. Чего тут комментировать?
ИМХО всё и так ясно. Надо нормальный метод делать типа там IsValid или IsInited или ещё какой. А не огород городить.
Впрочем, если хочется огорода...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: NULL вместо объекта класса
От: Аноним  
Дата: 05.12.07 16:34
Оценка:
Здравствуйте, Sr.Melifaro, Вы писали:

SM>Приветствую, уважаемые господа!


SM>Интересует следующий вопрос:

SM>Есть массив объектов класса [3][3][3]. Некоторые из них проинициализированы значениями. Остальные создаются дефолтовым конструктором. Можно ли вместо проверки на то, был ли объект массива создан по дефолту использовать проверку на NULL и не создавать дефолтовых объектов вообще? Тоесть хранить NULL вместо них?

Еще можна сделать виртуальный массив, который будет хранить только созданные обьекты. То бишь при размере [1000000][1000000][1000000] массив будет занимать места немного, если конечно дефолтовых обьектов много.
Re[2]: NULL вместо объекта класса
От: Аноним  
Дата: 05.12.07 17:52
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Еще можна сделать виртуальный массив, который будет хранить только созданные обьекты. То бишь при размере [1000000][1000000][1000000] массив будет занимать места немного, если конечно дефолтовых обьектов много.


Не в этой задаче. Здесь массив всегда строго [3][3][3].

PS: Задав один вопрос — ушел читать на долго Спасибо всем! Воспользовался методом IsNothing().
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.