Russian Qt Forum
Октябрь 02, 2024, 07:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Эмуляция null-объекта  (Прочитано 14999 раз)
BRE
Гость
« Ответ #30 : Март 16, 2012, 19:50 »

Увы, это будет слишком долго. У векторов размерность десятки тысяч, и подобная проверка где-нибудь в operator[] существенно замедлит программу.
Хорошо, пробуем так:
Код
C++ (Qt)
class vector_base
{
public:
virtual void method1() = 0;
virtual void method2() = 0;
};
 
class null_vector : public vector_base
{
public:
virtual void method1(); // посылает исключение
virtual void method2(); // посылает исключение
};
 
class valid_vector : public vector_base
{
public:
valid_vector( int size ) { ... }
 
virtual void method1(); // выполняет действие
virtual void method2(); // выполняет действие
};
 
// =========================================================
 
class vector
{
public:
vector() : m_vec( new null_vector ) {}
vector( int size ) : m_vec( new valid_vector( size ) ) {}
 
void setup( int size )
{
delete m_vec;
m_vec = new valid_vector( size );
}
 
void medhod1()
{
m_vec->method1();
}
 
void medhod2()
{
m_vec->method2();
}
 
private:
vector_base *m_vec;
};
 
« Последнее редактирование: Март 16, 2012, 19:52 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Март 16, 2012, 20:41 »

Напр vector_base это std::valarray о котором упоминал m_ax. Тогда чтобы передать весь его ф-ционал в Ваш vector - надо очень много делегироваться. А если сделать член public - обращения раздует изрядно.
Записан
BRE
Гость
« Ответ #32 : Март 16, 2012, 20:44 »

Напр vector_base это std::valarray о котором упоминал m_ax. Тогда чтобы передать весь его ф-ционал в Ваш vector - надо очень много делегироваться. А если сделать член public - обращения раздует изрядно.
А что делать. Хотим скорости и что бы тогда проверялось, а тогда нет.

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #33 : Март 16, 2012, 22:56 »

Увы, это будет слишком долго. У векторов размерность десятки тысяч, и подобная проверка где-нибудь в operator[] существенно замедлит программу.
Хорошо, пробуем так:
Код
C++ (Qt)
class vector_base
{
public:
virtual void method1() = 0;
virtual void method2() = 0;
};
 
class null_vector : public vector_base
{
public:
virtual void method1(); // посылает исключение
virtual void method2(); // посылает исключение
};
 
class valid_vector : public vector_base
{
public:
valid_vector( int size ) { ... }
 
virtual void method1(); // выполняет действие
virtual void method2(); // выполняет действие
};
 
// =========================================================
 
class vector
{
public:
vector() : m_vec( new null_vector ) {}
vector( int size ) : m_vec( new valid_vector( size ) ) {}
 
void setup( int size )
{
delete m_vec;
m_vec = new valid_vector( size );
}
 
void medhod1()
{
m_vec->method1();
}
 
void medhod2()
{
m_vec->method2();
}
 
private:
vector_base *m_vec;
};
 

Или можно написать просто маленький классик "затычку", вместо иерархии векторов:
Код
C++ (Qt)
struct base_state
{
   virtual void police() = 0;
};
 
struct null_state : public base_state
{
   virtual void police() { throw exception; } // Кидаем исключения
};
 
struct valid_state : public base_state
{
   virtual void police() {}  // Ничего не делаем, просто пропускаем.
};
 
class vector
{
public:
vector() : m_state( new null_state ) {}
vector( int size ) : m_state( new valid_state) {}
 
void setup( int size )
{
delete m_state;
m_state = new valid_state;
}
 
void medhod1()
{
m_state->police();
               ....
               ....
}
 
void medhod2()
{
   m_state->police();
           ....
           ....
}
 
private:
   base_state    *m_state;
};
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
BRE
Гость
« Ответ #34 : Март 16, 2012, 23:01 »

Но все таки, такие вещи должны отслеживаться на этапе разработки и отлавливаться механизмами типа assert еще во время отладки. Тащить это в релиз, IMHO, избыточно.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #35 : Март 16, 2012, 23:07 »

Но все таки, такие вещи должны отслеживаться на этапе разработки и отлавливаться механизмами типа assert еще во время отладки. Тащить это в релиз, IMHO, избыточно.


Это да, но у меня почему-то такое ощущение, что Чёрный странник что-то другое имел в виду.. Я вот так до конца и не понял, какого поведения от вектора он хотел получить(
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
BRE
Гость
« Ответ #36 : Март 16, 2012, 23:16 »

У меня такое же ощущение. Подождем, что он скажет про наши перлы, может будет понятней. Улыбающийся

2 Черный странник а еще лучше в коде покажи: "Хочу вот так". Не обязательно что бы это компилировалось.
Записан
Blackwanderer
Гость
« Ответ #37 : Март 17, 2012, 07:06 »

В чем проблема
Код
C++ (Qt)
class Solver
{
public:
Solver(): x(){
// Why we create some vector at this point? Why you choose such dimension for vector?
// We don't know anything about it. And we don't understad what is vector of zero dimension.
// Is it valid? Can we use it? Will be it used somewhere?
....
// Only now we know dimension of vector
x = Vector(dimension);
}
private:
Vector x;
}
 

Что хочу:
Код
C++ (Qt)
class Solver
{
public:
Solver(): x(null){
// It is obviously that x is null-object. We don't know anything about it.
// Any action with x should crash program. Only assigment allowed.
....
// Now we know dimension of vector
x = Vector(dimension);
}
private:
Vector x;
}
 

На данный момент больше всего мне понравился совет от Igors
Код
C++ (Qt)
typedef Vector NullVector
 
class Solver
{
public:
Solver(): x(NullVector()){
// It will not crash, but at least it is clear that vector x is null-object.
....
// Now we know dimension of vector
x = Vector(dimension);
}
private:
Vector x;
}
 

С виртуализацие будет работать. Это достаточно известный Null Object Pattern. Но проблема в том, что тогда перестанет работать inline, что крайне отрицательно скажется на скорости. А поскольку это всего лишь хотелка, то скорость превыше красоты.
P.S. В теге {code=cpp-qt} можно корректно писать кириллицей?
Записан
BRE
Гость
« Ответ #38 : Март 17, 2012, 08:25 »

Но мне так и не понятно, почему ты не хочешь использовать assert во всех методах, с проверкой на нулевую размерность?
Проверка будет работать только для debug-сборки, в релизе от нее не останется и следа. И будешь гарантировано получать по рукам при попытке использовать такой вектор.
Записан
Akon
Гость
« Ответ #39 : Март 17, 2012, 10:36 »

Цитировать
Хочу заведомо некорректный объект класса причем как с логической точки зрения (объект должен быть некорректен с точки зрения предметной области) ...
ОК, приведите пример некорректного вектора с т.з. линейной алгебры.

ИМХО, все что вам нужно - Vector::isValid(). Обобщенное решение задачи (когда у типа нет специального null значения (специального метода isValid()) - boost::optional.
Записан
Blackwanderer
Гость
« Ответ #40 : Март 17, 2012, 16:51 »

Но мне так и не понятно, почему ты не хочешь использовать assert во всех методах, с проверкой на нулевую размерность?
Проверка будет работать только для debug-сборки, в релизе от нее не останется и следа. И будешь гарантировано получать по рукам при попытке использовать такой вектор.
Кстати да, что-то я ступил. В купе с советом от Igors про typedef будет почти близко к желаемому. Благодарствую.
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.215 секунд. Запросов: 23.