Russian Qt Forum

Программирование => С/C++ => Тема начата: AzazelloAV от Октябрь 07, 2015, 17:16



Название: С++ статик поля
Отправлено: AzazelloAV от Октябрь 07, 2015, 17:16
Это вечная тема, к которой я возращаюсь через некоторое время и решаю заново, что порядком надоело.

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

Есть некое перечисление. Мы заворачиваем это перечиление в класс (читайте в namespace),. Пишу "идеальный для меня" код.

Код:
class TagStatus {
public:
     enum Status {
         NoDefine,
         Define1,
        ......
     }
     static String convertToString(Status)
     static Status convertToEnum(String)
private:
    static StatusStr mStatusStr[3] = {"not define", "Что то стринг", ...}  
}

Где, где эту грёбанную mStatusStr, кроме как в конструкторе на проверку размера инициализировать, без отрыва от класса.

Как вы поняли, я просто прячу перечисление в класс и "прикидываюсь" что это обычное перечисление, понятно, перегрузку операторов всяких я опустил тут.

Яркий пример - QVariant::typeToName, только не отсылать к исходникам, там у них задачи посложней.

P.S. constexpr не валидно для строк.

P.S.2 Наверное сложно изьясняюсь, но задача следующая превратить перечиление в корабль, с преобразованием строки в перечисление и наоборот.

P.S.3 Никоим образом эта тема не пересекается с прятаньем приватов в C++ файлы. Разный посыл.


Название: Re: С++ статик поля
Отправлено: __Heaven__ от Октябрь 07, 2015, 17:42
А std::map здесь не подходит?


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 07, 2015, 17:55
А std::map здесь не подходит?

В данном контексте мап и доступ по индексу не отличается.
Ну а второй вопрос (следующий из топика) - как мне инициализировать map значениями


Название: Re: С++ статик поля
Отправлено: Johnik от Октябрь 07, 2015, 18:24
Красиво можно решить на макросах. На макросах буста сделать это относительно просто.

P.S. Не надо обсуждать насколько красивым может быть решение на макросах, это же касается и буста. Использовать или не использовать макросы и/или буст решает каждый сам для себя.
P.P.S. AzazelloAV, если заинтересует - могу привести


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 07, 2015, 18:49
Красиво можно решить на макросах. На макросах буста сделать это относительно просто.

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


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 07, 2015, 18:52
Цитировать
Красиво можно решить на макросах.
Да, это как раз X-макросы..

Код
C++ (Qt)
namespace TagStatus {
 
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
 
#define X(a, b) b,
   static const char * mStatusStr[] = { STATUS };
#undef X
 
}
 


Название: Re: С++ статик поля
Отправлено: Johnik от Октябрь 07, 2015, 19:02
На макросах нельзя. Я превращаю переменную в класс. Представте сотни "переменных" на макросах, тогда лучше вообще отказаться от этой идеи и идти классическим путём. Этож какая нечитаемая простыня будет....

Выглядит примерно так:
Код:
ENUM(TestEnum, (v1) (v2) (v3));


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 07, 2015, 19:04
Цитировать
Красиво можно решить на макросах.
Да, это как раз X-макросы..

Код
C++ (Qt)
namespace TagStatus {
 
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
 
#define X(a, b) b,
   static const char * mStatusStr[] = { STATUS };
#undef X
 
}
 

Э нет ребят, мы в какой-то камменый век скатываемся. Этож всего лишь частное решение, а вы его как всегда в лоб. Вы хотите все определить "компиле тайм" макросами, которые нельзя теститовать (и так далее и так далее). Конечно, можно написать шаблоны для всех этих классов, только вот засада какая - их написание перекроет задачу и причём эти шаблоны никому не нужны, кроме меня. Т.е. пиши шаблоны, но забудь про проект, пиши макросы, но задудь про изменения.


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 07, 2015, 19:13
Цитировать
Этож всего лишь частное решение,
Нет, оно как раз более общее, чем руками проделывать то, что вы вначале привели.

X-макросы позволяют лекго удалять, добавлять новые элементы перечисления. Причём в одном месте. Дальше всё автоматически подставиться)

 
Цитировать
макросами, которые нельзя теститовать (и так далее и так далее).
Вы о чём? Что именно здесь нельзя тестировать?


Название: Re: С++ статик поля
Отправлено: Johnik от Октябрь 07, 2015, 19:13
Тогда напишите Wizard(или скрипт какой...), который за вас всю подноготную нагенерит.


Название: Re: С++ статик поля
Отправлено: __Heaven__ от Октябрь 07, 2015, 20:03
Я про такой вариант
Код
C++ (Qt)
class TagStatus {
public:
    enum Status {
        NoDefine,
        Define1,
        Define2
    };
    static String convertToString(Status);
    static Status convertToEnum(String);
private:
   static const std::map<Status, String> mStatusStr;
};
 
const std::map<TagStatus::Status, String> TagStatus::mStatusStr = {
   {NoDefine, "not define"},
   {Define1,  "Что то стринг"},
   {Define2,  "..."}
};
 


Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 08, 2015, 08:49
Я про такой вариант
Не знаю как С++11, но "до того" такая инициализация мапы не пройдет, нужно объявлять конструктор. Поиск "по строке" мапа тоже не решает, его каждый раз придется дописывать. Все это не смертельно, но возня которой, полагаю, ребятенок хотел избежать.  Вообще мапа здесь не очень, тех эл-тов макс десятки, просто перебор вполне приемлем. Я делал так
Код
C++ (Qt)
typedef QPair <const char *, SInt32> TNameType;  // тут по-хорошему нужны темплейт аргументы
 
struct CPairTable : public QList <TNameType> {
SInt32 Name2Type ( const QString & name ) const;
QString Type2Name ( SInt32 ID ) const;
QString PrintError ( const QString & badName ) const;
int IndexOfName ( const QString & name ) const;
int IndexOfType ( SInt32 ID ) const;
 
template <class T>    
CPairTable & operator << ( const T & value )  // чтобы добавлять эл-ты в объявлении const
{
return (CPairTable &) (QList <TNameType>::operator << (value));
}
};
 


Название: Re: С++ статик поля
Отправлено: Racheengel от Октябрь 08, 2015, 09:17
С макросами костыль конечно аццкий  ;)

Но имхо другое еще хуже...


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 08, 2015, 09:30
Вот интересное на мой взгляд решение https://github.com/flaub/boost-enum:
Код
C++ (Qt)
BOOST_ENUM(Level,
   (Abort)("unrecoverable problem")
   (Error)("recoverable problem")
   (Alert)("unexpected behavior")
   (Info)("expected behavior")
   (Trace)("normal flow of execution")
   (Debug)("detailed object state listings")
)
 
int main()
{
   foreach(const string& name, Level::names)
   {
       cout << name << endl;
   }
   cout << "1: " << Level::names[1] << endl;
   cout << "toString(Abort): " << Level::toString(Level::Abort) << endl;
   cout << "getValue(Abort): " << Level::getValue(Level::Abort) << endl;
 
   Level::type value = Level::Invalid;
   bool ret = Level::fromString("Abort", value);
   cout << "fromString(\"Abort\"): " << ret << ", " << value << endl;
 
   value = Level::Invalid;
   ret = Level::fromString("Debug", value);
   cout << "fromString(\"Debug\"): " << ret << ", " << value << endl;
 
   value = Level::Invalid;
   ret = Level::fromString("not in enum", value);
   cout << "fromString(\"not in enum\"): " << ret << ", " << value << endl;
 
   return 0;
}
 

Цитировать
Abort
Error
Alert
Info
Trace
Debug
Invalid
1: Error
toString(Abort): Abort
getValue(Abort): unrecoverable problem
fromString("Abort"): 1, 0
fromString("Debug"): 1, 5
fromString("not in enum"): 0, 6


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 08, 2015, 12:57
Нашёл простое решение, которое подходит для меня

Код
C++ (Qt)
class TagStatus {
public:
    enum Status {
        NoDefine,
        Define1,
        Define2
    };
    static String convertToString(Status);
    static Status convertToEnum(String);
private:
   static class HashStr: public<String,enum> {
        HashStr() {
            insert("Not define",NoDefine);
            ......
        }
   } mHashStr;
};
 

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

Цитировать
Вот интересное на мой взгляд решение https://github.com/flaub/boost-enum:
Цитировать
Решение такое я думаю тоже подойдёт. Я все таки его не исследовал, поэтому однозначного ответа дать не могу.




Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 08, 2015, 13:14
Нашёл простое решение, которое подходит для меня

Код
C++ (Qt)
class TagStatus {
public:
    enum Status {
        NoDefine,
        Define1,
        Define2
    };
    static String convertToString(Status);
    static Status convertToEnum(String);
private:
   static class HashStr: public<String,enum> {
        HashStr() {
            insert("Not define",NoDefine);
            ......
        }
   } mHashStr;
};
 

Конечно, код у меня другой, но смысл понятен.
А где convertToString? И если строчек с десяток - все равно в хедере малевать?


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 08, 2015, 13:33
Цитировать
Нашёл простое решение, которое подходит для меня
Тогда уж лучше так:
Код
C++ (Qt)
struct TagStatus
{
   enum Status {
       NoDefine,
       Define1,
       Define2
   };
 
   static std::string convertToString(Status s) { return get_hash().at(s); }
 
   static Status convertToStatus(const std::string & s)
   {
       for (auto & x : get_hash())
       {
           if (s == x.second)
               return x.first;
       }
       throw std::bad_cast();
   }
 
private:
   typedef std::map<Status, std::string> hash_type;
 
   static const hash_type & get_hash()
   {
       static hash_type hash =
       {
           {NoDefine, "No Define"},
           {Define1, "Define 1"},
           {Define2, "Define 2"}
       };
       return hash;
   }
};
 

Но это всё равно плохие решения, поскольку главная проблема остаётся: Править энум (что-то новое добавить, что-то удалить, что-то поменять местами или..) придётся в двух местах.
А это потенциальное узкое место, сами знаете для чего..  


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 08, 2015, 13:38
Нашёл простое решение, которое подходит для меня

Код
C++ (Qt)
class TagStatus {
public:
    enum Status {
        NoDefine,
        Define1,
        Define2
    };
    static String convertToString(Status);
    static Status convertToEnum(String);
private:
   static class HashStr: public<String,enum> {
        HashStr() {
            insert("Not define",NoDefine);
            ......
        }
   } mHashStr;
};
 

Конечно, код у меня другой, но смысл понятен.
А где convertToString? И если строчек с десяток - все равно в хедере малевать?

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

Ну а насчет наоборот - определите класс public<enum,String>, аналогия понятна. Можно обычный массив, если мы уверены, что енумы у нас не будут пронумерованы ручками. И конечно одна точка входа строки - т.е. строку мы определяем только раз. Другими словами консруктор будет выглядить так (если не попутал с названиями).

Код:
    mHashStr.insert(mHashEnum[enum],enum);

Большой ли оверхед - не знаю. По производительности то точно оптимально, по объёму откомпилированного кода - возможно


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 08, 2015, 13:42

Но это всё равно плохие решения, поскольку главная проблема остаётся: Править энум (что-то новое добавить, что-то удалить, что-то поменять местами или..) придётся в двух местах.
А это потенциальное узкое место, сами знаете для чего..  

Это да, и тут средствами компилятора не обойтись. Остаётся только шаблон. Но с другой стороны не такое критичное, мы  можем только напортачить со строками и перекрывать данную проблему тестированием с ассертами


Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 08, 2015, 14:01
Вынесете конструктор ...
... определите класс ...
Да я вообще-то ничего делать не собирался - так, принял участие в обсуждении  :) Вы же написали convertToString - вот я и спросил. Да, а если у второго класса такая же котавасия (все как TagStatus, только enum и строки другие) - тоже ему класс определять? И 2 хеша тоже создавать?

По производительности то точно оптимально...
Ой  :)


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 08, 2015, 14:03
Цитировать
Но с другой стороны не такое критичное, мы  можем только напортачить со строками и перекрывать данную проблему тестированием с ассертами
Вы так и не ответили на мой вопрос:  где в этом случае (см. слегка переработанный код) могут возникнуть проблемы при тестировании?:
Код
C++ (Qt)
struct TagStatus
{
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
   static std::string convertToString(Status s) { return get_hash().at(s); }
 
   static Status convertToStatus(const std::string & s)
   {
       for (auto & x : get_hash())
       {
           if (s == x.second)
               return x.first;
       }
       throw std::bad_cast();
   }
 
private:
   typedef std::map<Status, std::string> hash_type;
 
   static const hash_type & get_hash()
   {
#define X(a, b) {a, #b},
       static hash_type hash = { STATUS };
#undef X
       return hash;
   }
};
 
Здесь мы правил энум только в одном месте и всё.


Название: Re: С++ статик поля
Отправлено: __Heaven__ от Октябрь 08, 2015, 14:23
Код
C++ (Qt)
#define X(a, b) {a, #b},
 
Что означает решетка перед b?


Название: Re: С++ статик поля
Отправлено: Racheengel от Октябрь 08, 2015, 14:53
#5 буст за собой не тащит, но... "Мои глазааа!!!"
Да и несколько энамов в одном файле не задефинировать.

#13 оптически покошерней (и функциональней, наверное, тоже) :) но тащит буст мертвым грузом, у нас бы на конторе не прошло :(

Остальное, увы, треш какой-то :(


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 08, 2015, 14:57
Цитировать
Что означает решетка перед b?
Криминальное прошлое переменной b  ;D

Этот оператор # превращает b в строковый литерал (кавычки, короче, ставит двойные: "b").
Хотя в этом случае:
Код
C++ (Qt)
#define X(a, b) {a, #b},
 
он и не нужен.. можно просто
Код
C++ (Qt)
#define X(a, b) {a, b},
 


Название: Re: С++ статик поля
Отправлено: __Heaven__ от Октябрь 08, 2015, 15:15
:) спс


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 08, 2015, 16:00
Цитировать
Но с другой стороны не такое критичное, мы  можем только напортачить со строками и перекрывать данную проблему тестированием с ассертами
Вы так и не ответили на мой вопрос:  где в этом случае (см. слегка переработанный код) могут возникнуть проблемы при тестировании?:
Код
C++ (Qt)
struct TagStatus
{
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
   static std::string convertToString(Status s) { return get_hash().at(s); }
 
   static Status convertToStatus(const std::string & s)
   {
       for (auto & x : get_hash())
       {
           if (s == x.second)
               return x.first;
       }
       throw std::bad_cast();
   }
 
private:
   typedef std::map<Status, std::string> hash_type;
 
   static const hash_type & get_hash()
   {
#define X(a, b) {a, #b},
       static hash_type hash = { STATUS };
#undef X
       return hash;
   }
};
 
Здесь мы правил энум только в одном месте и всё.

Проблемы при тестировании в вашем коде не будет.

Я имел в виду глобальные вещи. Проблемы при тестировании с макросами как таковые отсутствуют. Но на практике они трудноуловимы по совсем другим причинам:
Перегруженый код - макросы не вписываются в язык, код становится вырвиглазным.
Есть макросы "возможностей" и макросы "дебага". И чем больше макросов.... Их даже трудно с ветвлениями if сравнивать. Сколько вариантов их включения нужно протестировать со всеми остальными.

В вашем случае, это макрос, потому как макрос :), он был, есть и будет. Скажем так, для меня некомфортно использовать макросы прежде всего из-за 1-го пункта. Для меня ваш код понятет (ну почти), и, кстати, красив в плане решения, но всё одно вырвиглазный.

Считайте моё решение необоснованным. Я даже из за вырвиглазности готов написать шаблон, который по определению вообще адски сложно тестировать.

Мне кажется после прочтения Александреску многие программисты на С++ чуствуют себя ущербными. Но ничего, мы скоро объеденим функциональное программирование и метапрограммирование в плюсах и тогда точно не будет ни одного человека, который скажет, что знает плюсы, даже его разработчика можно засмеять.


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 08, 2015, 16:18
Да, а если у второго класса такая же котавасия (все как TagStatus, только enum и строки другие) - тоже ему класс определять? И 2 хеша тоже создавать?
А как же. Разве в этом мире существуют другие решения? Не хотим ручками по правилам создавать - пишем шаблон. Нет, ну оно то конечно можно от этого отойти, привязав enum к int.

По производительности то точно оптимально...
Цитировать
Ой  :)

Подробнее про ой. Он же статик, один раз создался и айда работать. Чем вас смущает создание хешей или мапов. Ну уж точно лучше кейсов для сотни классов, тем более для одного из хешей можно указатель использовать, а не саму строку.


Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 08, 2015, 16:54
А как же. Разве в этом мире существуют другие решения?
Ну вот напр вынести это в отдельный класс. Пусть пока и без шаблонов, навскидку и не вспомню когда мне потребовалось что-то другое кроме "строка + ID"

Подробнее про ой. Он же статик, один раз создался и айда работать. Чем вас смущает создание хешей или мапов.
Контейнеру нужно какое-то число эл-тов чтобы он проявил свои лучшие качества. А до десяти тупой перебор точно будет быстрее. До ста (примерно) тоже можно обойтись перебором.


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 08, 2015, 17:03
Контейнеру нужно какое-то число эл-тов чтобы он проявил свои лучшие качества. А до десяти тупой перебор точно будет быстрее. До ста (примерно) тоже можно обойтись перебором.
Да это всё понятно. Я же код не в IDE пишу, а в броузере, для примера. Тут же предоставляют общие решения, ну не будет там много значений, но это частности. Главное шаблонность (не в плане шаблонов С++) и решения, а не реализация (про данный топик). Я вообще думаю массивы использовать, без всяких контейнеров. В данном случае вы переходите на другой уровень, на реализацию, которую здесь не обсуждают. Это как про хеадер.


Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 09, 2015, 03:30
Вы так и не ответили на мой вопрос:  где в этом случае (см. слегка переработанный код) могут возникнуть проблемы при тестировании?:
Код
C++ (Qt)
struct TagStatus
{
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
   static std::string convertToString(Status s) { return get_hash().at(s); }
 
   static Status convertToStatus(const std::string & s)
   {
       for (auto & x : get_hash())
       {
           if (s == x.second)
               return x.first;
       }
       throw std::bad_cast();
   }
 
private:
   typedef std::map<Status, std::string> hash_type;
 
   static const hash_type & get_hash()
   {
#define X(a, b) {a, #b},
       static hash_type hash = { STATUS };
#undef X
       return hash;
   }
};
 
Здесь мы правил энум только в одном месте и всё.
Ну я бы не назвал это впечатляющим успехом :) Сэкономили на 4 enum,  зато потратились на #define/#undef и создали маленький ребус (не спорю - элегантный, остроумный) который потребует осмысления. Пусть менее минуты - но все же.

И еще мне несимпатично: когда браузер вывел меня на объявление члена hash - хотелось бы сразу видеть чем он инициализируется. А тут надо подыматься вверх для обозрения STATUS

И содержательная часть (ф-ционал) как-то заслонена "синтаксическим сахаром". По одному ищем с ключом, по другому перебором - неоднообразно. Заряжали бы уж сразу boost::bitmap.


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 09, 2015, 12:45
Цитировать
И содержательная часть (ф-ционал) как-то заслонена "синтаксическим сахаром". По одному ищем с ключом, по другому перебором - неоднообразно. Заряжали бы уж сразу boost::bitmap.
Ну здесь да, если логика этого класса подразумевает полную симметрию (хотя я не вижу зачем она здесь нужна и метод convertToStatus в частности), то bimap более уместен.
Однако он не имеет конструктора    c initializer_list и поэтому так написать не получится
Код
C++ (Qt)
typedef boost::bimap<Status, std::string> hash_type;
 
   static const hash_type & get_hash()
   {
#define X(a, b) {a, b},
       static hash_type hash = { STATUS }; // так не прокатит..
#undef X
 


Хотя, с другой стороны, есть boost::assign и тогда можно так:
Код
C++ (Qt)
typedef boost::bimap<Status, std::string> hash_type;
 
   static const hash_type & get_hash()
   {
#define X(a, b) (a, b)
       static hash_type hash = boost::assign::list_of<hash_type::relation> STATUS;
#undef X
       return hash;
   }
 


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 09, 2015, 16:41
Ну здесь да, если логика этого класса подразумевает полную симметрию (хотя я не вижу зачем она здесь нужна и метод convertToStatus в частности), то bimap более уместен.

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


Название: Re: С++ статик поля
Отправлено: m_ax от Октябрь 09, 2015, 16:59
Цитировать
Все наоборот. Основная работа класса - это статус.
А, ну тогда понятно..


Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 09, 2015, 17:12
Все наоборот. Основная работа класса - это статус. Статус получаем от строки. А статус в строку - это для вспомогательных вещей, ну к примеру запихнуть в модель, чтобы видеть значения и не придумывать в модели свои значния. На практике класс может быть односторонним, а не зеркальным.
Непонятное деление на "основной" и нет. С точки зрения кода затраты те же. Помню мне потребовалось: если строка невалидна (для нее нет статуса), то выдать месягу "'LaLa' is not a valid name\nThe valid names are <list>". Конечно написать это минута. Но вот где разместить этот код - не так уж просто решить :) Как бы Вы поступили?


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 09, 2015, 17:21
Как бы Вы поступили?
Не позволил пользователю вводить невалидные строки. Для этого есть куча способов от форматов и валидаторов и до QComboBoxов и комплитеров...


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 08:24
Непонятное деление на "основной" и нет. С точки зрения кода затраты те же. Помню мне потребовалось: если строка невалидна (для нее нет статуса), то выдать месягу "'LaLa' is not a valid name\nThe valid names are <list>". Конечно написать это минута. Но вот где разместить этот код - не так уж просто решить :) Как бы Вы поступили?

Я люблю исключения, поэтому мне проще.

А про основной всё прозрачно. Можно вообще отказаться от перечисления и хранить только строку. Тогда мы теряем гибкость в компиле тайм, нам прийдётся использовать строки для изменения, а так как мы не хотим использовать строки (можем же ошибиться), то строка должна быть определена в одном месте. А раз в одном месте, значит определяем её константами, т.е. прийдём к  дефайнам. По сравнению с дефайнами, константы енум мне лучше выглядят. Ещё есть вариант использовать хеш строкИ, как константу, тоже можно придумать элегатное решение.

А насчет как бы я поступил, точнее как я делаю.
Начнем с того, что объекты имеют атрибуты, которые обязательны и не обязательны + некоторые имеют дефолтные значение.
Итог - другого выхода нет, как решить, что объект не атомарен. Т.е. должен иметь метод(ы) (save/load, check, post/cancel, open/close или какой другой), который его переводит в стабильное состояние либо говорит, что он не валидный (невалидность тоже можно рассматривать как стабильное состояние). Не данный класс, который мы обсуждаем, а класс, который содержит его.

Не позволил пользователю вводить невалидные строки. Для этого есть куча способов от форматов и валидаторов и до QComboBoxов и комплитеров...
На самом деле таких способов не много. Если брать гуи, то валидация с комбобоксом может прокатить, но мы же пишем модульный код, правильно. С чего это мой модуль обработки данных должен быть на 100% уверен что ему правильные данные передадут?
А если данные с файла читаем? Даже это наш записанный файл, где увереность что не поменялся битик. Тут офис иногда падает из за битых файлов, я уже не говорю про взлом.

Валидация отдельно - ну это как то даже странно. Кто как не лучше знает про данные, как класс, который работает с этими данными, не ему ли валидацию делать. Или у нас будет два разных модуля, один проверяет валидность, второй уже разбирает данные. Возможно, вы имели ввиду валидацию на стороне клиента(не про клиент-серверные технологии говорится). Да, такая валидация существует, но лишь для удобства пользователя, а на стороне обработких данных все равно проверяется.

Яркий пример разрозненной валидации - IDE. Он делает парсинг файла отдельно от компилятора (подсветка синтаксиса и ошибок). Смогли бы договориться по айпи, сколько себе бы сэкономили и на новый уровень иде вышла бы.


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 11:35
Если брать гуи, то валидация с комбобоксом может прокатить, но мы же пишем модульный код, правильно.
А как модульный код может помешать валидировать вводимые пользователем данные?




Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 11:46
Если брать гуи, то валидация с комбобоксом может прокатить, но мы же пишем модульный код, правильно.
А как модульный код может помешать валидировать вводимые пользователем данные?

Я же выше отписался.
Повторюсь. . Да, такая валидация существует, но лишь для удобства пользователя, а на стороне обработких данных все равно проверяется.

P.S.
Если бы вы писали оболочку для компакта (ауторан который, давайте установим), тогда любой бы не парился и валидация гуи хватило бы


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 11:51
Повторюсь. . Да, такая валидация существует, но лишь для удобства пользователя, а на стороне обработких данных все равно проверяется.
Скорее это не валидация, а способ не дать пользователю ввести не валидные данные.
Это лучше, чем давать пользователю вводить что попало, а потом информирование его об этом.
На что я собственно и написал свой первый комментарий.

А проверка входных данных - это несколько другое. Если есть вариант, что могут прийти не валидные данные, то их придется проверять всегда.


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 11:57
Повторюсь. . Да, такая валидация существует, но лишь для удобства пользователя, а на стороне обработких данных все равно проверяется.
Скорее это не валидация, а способ не дать пользователю ввести не валидные данные.
Это лучше, чем давать пользователю вводить что попало, а потом информирование его об этом.
На что я собственно и написал свой первый комментарий.

А проверка входных данных - это несколько другое. Если есть вариант, что могут прийти не валидные данные, то их придется проверять всегда.

Так, видно ник так влияет, какая то вода уже пошла.
Вдумайтесь в фразу: Скорее это не валидация, а способ не дать пользователю ввести не валидные данные.

Да мы воду в ступе с вами толчём, как на первом курсе. Все же знают, что дикое количесво кода это тупая проверка данные. Надоедливая, с тестированием, которая может забирать 70% производительности. Зачем нам говорить о свершившихся фактах, которые уже устоялись и поднимать их на поверхность, это же должно быть "из под коробки" для программиста.


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 12:04
Так, видно ник так влияет, какая то вода уже пошла.
Вдумайтесь в фразу: Скорее это не валидация, а способ не дать пользователю ввести не валидные данные.
А что вам не понятно в фразе? В чем вы видите воду?
Если у объекта есть несколько состояний и пользователь должен выбрать одно из них, то ему нужно дать возможность выбирать исключительно из этих состояний (combobox), а не разрешить ему вводить любые данные, а потом проверять - угадал он одно из состояний или нет.

Да мы воду в ступе с вами толчём, как на первом курсе.Да мы воду в ступе с вами толчём, как на первом курсе.
Ну не знаю, я с вами никакую воду не толку. Я написал свое мнение на пост Igors.


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 12:11
Так, видно ник так влияет, какая то вода уже пошла.
Вдумайтесь в фразу: Скорее это не валидация, а способ не дать пользователю ввести не валидные данные.
А что вам не понятно в фразе? В чем вы видите воду?
Если у объекта есть несколько состояний и пользовтель должен выбрать одно из них, то ему нужно дать возможность выбирать исключительно из этих состояний (combobox), а не разрешить ему вводить любые данные, а потом проверять - угадал он одно из состояний или нет.


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

Или работая с БД, что это поле обязательно никак не пересекается с проверкой БД на присутствие значений. Это только для удобства, только. Никак больше. Удобства пользователя. Ну ещё для экономии траффика.

Тут я привёл клиент-серверные технологии лишь потому, что они понятны. Мы говорим про разные уровни. Есть валидация на стороне клиента ил нету, обработке данных это наплевать. Он должен сделать валидацию. Поэтому, рассматривать ваш вариант в данном контексте просто не уместно.


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 12:15
Это вам так кажется, что он никак не пересекается. :)

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


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 12:28
Это вам так кажется, что он никак не пересекается. :)

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

Совершенно верно. Но можем мы сделать так? Неа. Отбросим клиент-сервернные технологии, что результат может быть подделан по пути, мы их лишь для примера привели. Но у нас два разных класса, один на клиенте, второй на сервере. А как мы можем делегировать валидацию на другой класс? Никак, все равно проверка должна быть только в текущем, который работает с данными. Как обезопасить этот путь от клиента к серверу. Только создать жёсткие правила, в которых легко ошибиться.

Есть приверы валидации на внешнем классе? конечно. Возьмём к приверу Qt приват классы. Верхний класс может гарантировать, что данные прийдут валидные, он их проверит на своем уровне. Но это настолько специфичный частный пример, с такими ограничениями, что его даже рассматривать не стоит.


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 12:40
Понимаете, я в своем сообщении комментировал конкретный пост про GUI. :)
И все выше сказанное мной относиться к GUI.

Если вы получаете состояние из вне, то его нужно проверить в методе класса, который этим состоянием обладает. И я не очень понимаю в чем сложность подобной проверки для вас.


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 12:50
Понимаете, я в своем сообщении комментировал конкретный пост про GUI. :)
И все выше сказанное мной относиться к GUI.

Если вы получаете состояние из вне, то его нужно проверить в методе класса, который этим состоянием обладает. И я не очень понимаю в чем сложность подобной проверки для вас.

Я думаю, мы просто не допоняли друг друга, а также вашу специфику общения с Игорем :) А также ещё то, что вы очень невнимательно читаете посты других.


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 13:06
Я думаю, мы просто не допоняли друг друга, а также вашу специфику общения с Игорем :) А также ещё то, что вы очень невнимательно читаете посты других.
А что тут внимательно читать, если 99% всех постов о том, как удобно и безопасно описывать перечисления и строки их обозначающие. Я привел решение, концептуально лучшее для меня.
Насчет общения с Igors... Он задал конкретный вопрос, я его прокомментировал. Все.
В чем моя невнимательность? То что в этот момент вы думали о другом...?


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 13:24
Я думаю, мы просто не допоняли друг друга, а также вашу специфику общения с Игорем :) А также ещё то, что вы очень невнимательно читаете посты других.
А что тут внимательно читать, если 99% всех постов о том, как удобно и безопасно описывать перечисления и строки их обозначающие. Я привел решение, концептуально лучшее для меня.
Насчет общения с Igors... Он задал конкретный вопрос, я его прокомментировал. Все.
В чем моя невнимательность? То что в этот момент вы думали о другом...?

Я так понял, последнее слово должно быть за вами. Ну что-ж, посмотрим.


Название: Re: С++ статик поля
Отправлено: Igors от Октябрь 10, 2015, 14:08
Не понял куда зарулила тема :) Что я имел ввиду: вот предложено неск вариантов - и, на мой взгляд, любой хорош. Ок, работает. И вот возникла мааааленькая (да просто смешная) задачка
Цитировать
выдать месягу "'LaLa' is not a valid name\nThe valid names are <list>
Ну "list" - список всех валидных имен, возможно по алфавиту. Откуда та задачка взялась - не суть, ну вот "так надо". И выясняется что класс (который выглядел так прилично) почему-то очень плохо справляется с такой чепухой. Прямо какой-то "Devil is in the detail"  :)


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 14:36
Ну что-ж, посмотрим.
Это угроза?  ::)


Название: Re: С++ статик поля
Отправлено: Old от Октябрь 10, 2015, 14:42
Не понял куда зарулила тема :) Что я имел ввиду: вот предложено неск вариантов - и, на мой взгляд, любой хорош. Ок, работает. И вот возникла мааааленькая (да просто смешная) задачка
Цитировать
выдать месягу "'LaLa' is not a valid name\nThe valid names are <list>
Ну "list" - список всех валидных имен, возможно по алфавиту. Откуда та задачка взялась - не суть, ну вот "так надо". И выясняется что класс (который выглядел так прилично) почему-то очень плохо справляется с такой чепухой. Прямо какой-то "Devil is in the detail"  :)
Решение, которое я привел, это позволяет из коробки. Если какое-то решение это не позволяет, то это проблема самого решения. :)


Название: Re: С++ статик поля
Отправлено: AzazelloAV от Октябрь 10, 2015, 14:44
Ну что-ж, посмотрим.
Это угроза?  ::)

Честно, не хотел в этой теме больше отвечать. Но вы меня порвали! Это класс. Да, это угроза! Я не упомяну вас в своём завещании! Я вас прошу, не отвечайте, а то нас не поймут.