Кто-нибудь так делает?
От: Константин Л.  
Дата: 12.04.06 10:13
Оценка:

class MetadataType
{
    MetadataType();
    MetadataType( const MetadataType& );
    MetadataType& operator =( const MetadataType& );

public:

    enum Enum
    {
        CompanySymbol,
        CompanyName,
        Industry,
        Keyword,
        Other
    };
};


Позволяет четко квалифицировать значения энума.
Кто-нибудь так делает?
Re: Кто-нибудь так делает?
От: Demay  
Дата: 12.04.06 11:22
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>

КЛ>class MetadataType
КЛ>{
КЛ>    MetadataType();
КЛ>    MetadataType( const MetadataType& );
КЛ>    MetadataType& operator =( const MetadataType& );

КЛ>public:

КЛ>    enum Enum
КЛ>    {
КЛ>        CompanySymbol,
КЛ>        CompanyName,
КЛ>        Industry,
КЛ>        Keyword,
КЛ>        Other
КЛ>    };
КЛ>};

КЛ>


КЛ>Позволяет четко квалифицировать значения энума.

КЛ>Кто-нибудь так делает?

Я так делаю. В нижеследующем коде рад выслушать критику. Идея была такая, чтобы параметром шаблона мог выступить ограниченный набор вариантов:
....
#if defined(WIN32)
#include <windows.h>
#define GENERIC_READ_WRITE    (GENERIC_READ|GENERIC_WRITE)
#elif defined(_POSIX_)
#include <stdio.h>     /* 'sprintf'    */
#include <unistd.h>    /* 'lseek'      */
#include <fcntl.h>     /* 'open'       */
#include <sys/stat.h>  /* 'S_IRUSR,... */
#include <sys/syslimits.h> /* 'PATH_MAX,... */
#include <errno.h>    /* 'extern int errno' */
#include <string.h>   /* "char* strerror( int errnum ); */
#define CloseHandle(x)          close(x)
#define MAX_PATH                PATH_MAX
#define INVALID_HANDLE_VALUE    (-1)
#define CREATE_NEW              O_CREAT|O_EXCL
#define CREATE_ALWAYS           O_CREAT|O_TRUNC
#define OPEN_EXISTING           0
#define OPEN_ALWAYS             O_CREAT
#define TRUNCATE_EXISTING       O_TRUNC
#define GENERIC_READ            O_RDONLY
#define GENERIC_WRITE           O_WRONLY
#define GENERIC_READ_WRITE      O_RDWR
#define FILE_BEGIN              SEEK_SET
#define FILE_CURRENT            SEEK_CUR
#define FILE_END                SEEK_END
#define FILE_FLAG_WRITE_THROUGH O_SYNC
typedef int HANDLE;
#else
#error ERROR: WIN32 or POSIX supported!
#endif


class FileOpening {
public:
    enum Enum {
        CreateNew=CREATE_NEW,              //!< Creates a new file. The function fails if the specified file already exists.
        CreateAlways=CREATE_ALWAYS,        //!< Creates a new file. If the file exists, the function overwrites the file, clears the existing attributes, and combines the file attributes and flags specified by dwFlagsAndAttributes with FILE_ATTRIBUTE_ARCHIVE.
        OpenExisting=OPEN_EXISTING,        //!< Opens the file. The function fails if the file does not exist.
        OpenAlways=OPEN_ALWAYS,            //!< Opens the file, if it exists. If the file does not exist, the function creates the file as if dwCreationDisposition were CREATE_NEW.
        TruncateExisting=TRUNCATE_EXISTING //!< Opens the file. Once opened, the file is truncated so that its size is zero bytes. The calling process must open the file with at least GENERIC_WRITE access. The function fails if the file does not exist.
    };
};


class FileAccess {
public:
    enum Enum {
        ReadOnly=GENERIC_READ,             //!< Open file for reading only.
        ReadWrite=GENERIC_READ_WRITE,      //!< Open file for reading and writing.
        WriteOnly=GENERIC_WRITE            //!< Open file for writing only.
    };
};

................

template <
    enum FileOpening::Enum OpenTraits,
    enum FileAccess::Enum  AccessTraits = FileAccess::ReadOnly,
    enum FileShare::Enum   ShareTraits  = FileShare::NoShare
> class File {
public:


................
Re[2]: Кто-нибудь так делает?
От: Left2 Украина  
Дата: 12.04.06 11:46
Оценка:
Вот так вот навскидку — не вижу смысла параметризовать шаблон файла параметрами его открытия...
Зачем такие сложности?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Кто-нибудь так делает?
От: Demay  
Дата: 12.04.06 12:08
Оценка:
Здравствуйте, Left2, Вы писали:

L>Вот так вот навскидку — не вижу смысла параметризовать шаблон файла параметрами его открытия...

L>Зачем такие сложности?

Тут нет сложностей, просто работать с файлами в виде:
File<FileOpening::OpenExisting> file("post.txt");

немного проще и приятнее, чем вызвая функции API. Тем более что, после того как файл создан/открыт параметры типа GENERIC_READ|GENERIC_WRITE или O_CREAT|O_EXCL все равно уже не изменить
Re[4]: Кто-нибудь так делает?
От: Left2 Украина  
Дата: 12.04.06 12:11
Оценка: 4 (2) +5
Я не понял зачем параметризовать параметрами открытия шаблон?
В моём понимании параметры открытия должны быть параметрами конструктора.
Иначе (пример грубый) — если у тебя функция принимает файл, то тебе прийдётся явно указывать в параметрах функции что этот файл должен быть FileOpening::OpenExisting.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Кто-нибудь так делает?
От: Centaur Россия  
Дата: 12.04.06 12:29
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>
КЛ>class MetadataType
КЛ>{
КЛ>    MetadataType();
КЛ>    MetadataType( const MetadataType& );
КЛ>    MetadataType& operator =( const MetadataType& );
КЛ>public:
КЛ>    enum Enum
КЛ>    {
КЛ>        CompanySymbol,
КЛ>        CompanyName,
КЛ>        Industry,
КЛ>        Keyword,
КЛ>        Other
КЛ>    };
КЛ>};
КЛ>


Класс, объекты которого нельзя создавать, копировать и присваивать. Чем он принципиально лучше namespace?
Re[2]: Кто-нибудь так делает?
От: Константин Л.  
Дата: 12.04.06 12:33
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Здравствуйте, Константин Л., Вы писали:


КЛ>>
КЛ>>class MetadataType
КЛ>>{
КЛ>>    MetadataType();
КЛ>>    MetadataType( const MetadataType& );
КЛ>>    MetadataType& operator =( const MetadataType& );
КЛ>>public:
КЛ>>    enum Enum
КЛ>>    {
КЛ>>        CompanySymbol,
КЛ>>        CompanyName,
КЛ>>        Industry,
КЛ>>        Keyword,
КЛ>>        Other
КЛ>>    };
КЛ>>};
КЛ>>


C>Класс, объекты которого нельзя создавать, копировать и присваивать. Чем он принципиально лучше namespace?


Тем, что всегда придеться явно указывать имя класса, и с классами нельзя использовать
using
.
Re[5]: Кто-нибудь так делает?
От: Demay  
Дата: 13.04.06 10:29
Оценка: :)
Здравствуйте, Left2, Вы писали:

L>Я не понял зачем параметризовать параметрами открытия шаблон?

L>В моём понимании параметры открытия должны быть параметрами конструктора.
L>Иначе (пример грубый) — если у тебя функция принимает файл, то тебе прийдётся явно указывать в параметрах функции что этот файл должен быть FileOpening::OpenExisting.

Передавать параметры открытия конструктору, это привычка кодирования в стиле Си, объясните зачем передавать в конструктор или еще куда либо константы известные на этапе компиляции ?
Константы должны появится только один раз, в том месте где без них не обойтись, а проталкивать их по стеку не могу найти причину.
По отношению к файлу имеется ограниченный набор флагов для его открытия, читая Александреску раскладываем все варианты на стратегии и параметризуем ими шаблон. Указывая в параметрах функции что этот файл должен быть FileOpening::OpenExisting уже по объявлению легче определить что функция делает с файлом, она создает, удаляет или модифицирует существующий файл, весьма удобно.
Re[6]: Кто-нибудь так делает?
От: Left2 Украина  
Дата: 13.04.06 12:59
Оценка: 6 (1) +1
D>Передавать параметры открытия конструктору, это привычка кодирования в стиле Си, объясните зачем передавать в конструктор или еще куда либо константы известные на этапе компиляции ?

Такое "модное" кодирование заставит все функции сделать шаблонными. Приведёт это к непомерной нагрузке на компилятор — более-менее сложный проект будет собираться часами.

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


В случае шаблонного и не-шаблонного класса для вызова конструктора файла компилятор сгенерит одинаковый код (имею в виду вариант когда вызов конструктора будет инлайнится).

D>По отношению к файлу имеется ограниченный набор флагов для его открытия, читая Александреску раскладываем все варианты на стратегии и параметризуем ими шаблон. Указывая в параметрах функции что этот файл должен быть FileOpening::OpenExisting уже по объявлению легче определить что функция делает с файлом, она создает, удаляет или модифицирует существующий файл, весьма удобно.


Не стану оспаривать заслуги Александреску, но не стоит воспринимать всё им написанное как прямое руководство к действию. Книги его скорее дают представление о возможностях С++, чем являются практическим руководством. И уж тем более не стоит городить сложных решений там, где замечательно работают простые.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Кто-нибудь так делает?
От: megawatt Россия http://ruby.inuse.ru
Дата: 13.04.06 13:42
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Здравствуйте, Centaur, Вы писали:


C>>Здравствуйте, Константин Л., Вы писали:


КЛ>>>
КЛ>>>class MetadataType
КЛ>>>{
КЛ>>>    MetadataType();
КЛ>>>    MetadataType( const MetadataType& );
КЛ>>>    MetadataType& operator =( const MetadataType& );
КЛ>>>public:
КЛ>>>    enum Enum
КЛ>>>    {
КЛ>>>        CompanySymbol,
КЛ>>>        CompanyName,
КЛ>>>        Industry,
КЛ>>>        Keyword,
КЛ>>>        Other
КЛ>>>    };
КЛ>>>};
КЛ>>>


Достаточно было объявить закрытым только деструктор
Re[7]: Кто-нибудь так делает?
От: srggal Украина  
Дата: 13.04.06 13:50
Оценка: +1
Здравствуйте, Left2, Вы писали:

L>Не стану оспаривать заслуги Александреску, но не стоит воспринимать всё им написанное как прямое руководство к действию. Книги его скорее дают представление о возможностях С++, чем являются практическим руководством. И уж тем более не стоит городить сложных решений там, где замечательно работают простые.


Мои 5копеек:
Упоминание Стратегий Александреску в контексте примера Demay не есть правильно, ибо в примере используются traits, а не policy, в моём понимании Policy Флександреску это паттерн GoF Strategy в примере, мы не наблюдаем ничего подобного и видим обычные traits. Для использования стратегий Александреску применяет наследование, что тоже согласуется с с GoF, от traits'ов, в свою очередь, обычно не наследуются, видимо потому, что traits'ы применяются для других целей, это характеристики, и какие-либо утилитарные функции косвенно связанные ( в отличии от прямой связи у Policy ) с поведением.

И кроме того, в примере Demay сам же и называет шаблонные параметры XXXTraits



ЗЫ
Возможно я ошибаюсь, я буду очень признателен если меня поправят
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Кто-нибудь так делает?
От: Константин Л.  
Дата: 13.04.06 15:14
Оценка:
Здравствуйте, megawatt, Вы писали:

M>Здравствуйте, Константин Л., Вы писали:


КЛ>>Здравствуйте, Centaur, Вы писали:


C>>>Здравствуйте, Константин Л., Вы писали:


КЛ>>>>
КЛ>>>>class MetadataType
КЛ>>>>{
КЛ>>>>    MetadataType();
КЛ>>>>    MetadataType( const MetadataType& );
КЛ>>>>    MetadataType& operator =( const MetadataType& );
КЛ>>>>public:
КЛ>>>>    enum Enum
КЛ>>>>    {
КЛ>>>>        CompanySymbol,
КЛ>>>>        CompanyName,
КЛ>>>>        Industry,
КЛ>>>>        Keyword,
КЛ>>>>        Other
КЛ>>>>    };
КЛ>>>>};
КЛ>>>>


M>Достаточно было объявить закрытым только деструктор


Нет, тк я предпочитаю ошибки компиляции при



1)
void f( MetadataType );

2)
MetadataType* type1, type2;

....

*type1 = *type2;
Re[5]: Кто-нибудь так делает?
От: megawatt Россия http://ruby.inuse.ru
Дата: 13.04.06 16:04
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Нет, тк я предпочитаю ошибки компиляции при


КЛ>

КЛ>1)
КЛ>void f( MetadataType );

КЛ>2)
КЛ>MetadataType* type1, type2;

КЛ>....

КЛ>*type1 = *type2;

КЛ>


Ну и? Оба твоих пример не отработают с закрытым деструктором, кроме того
*type1 = *type2;
это ересть
Re[6]: Кто-нибудь так делает?
От: Константин Л.  
Дата: 13.04.06 17:16
Оценка:
Здравствуйте, megawatt, Вы писали:

M>Здравствуйте, Константин Л., Вы писали:


КЛ>>Нет, тк я предпочитаю ошибки компиляции при


КЛ>>

КЛ>>1)
КЛ>>void f( MetadataType );

КЛ>>2)
КЛ>>MetadataType* type1, *type2;//так

КЛ>>....

КЛ>>*type1 = *type2;

КЛ>>


M>Ну и? Оба твоих пример не отработают с закрытым деструктором, кроме того


не откомпилится только первый

M>*type1 = *type2;

M>это ересть
да, но мало ли
Re: Кто-нибудь так делает?
От: MaximE Великобритания  
Дата: 14.04.06 10:31
Оценка: +1
Константин Л. wrote:

> class MetadataType
> {
>     MetadataType();
>     MetadataType( const MetadataType& );
>     MetadataType& operator =( const MetadataType& );
> 
> public:
> 
>     enum Enum
>     {
>         CompanySymbol,
>         CompanyName,
>         Industry,
>         Keyword,
>         Other
>     };
> };

>
> Позволяет четко квалифицировать значения энума.
> Кто-нибудь так делает?

Делаю так:

namespace request_type {

enum type { none, master, add, update, get, del };

}

request_type::type parse(str_ref cmd, record_t*);


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 2.0
Re: Я и глава комитета по С++ так делаем
От: remark Россия http://www.1024cores.net/
Дата: 15.04.06 21:57
Оценка: 9 (1)
Здравствуйте, Константин Л., Вы писали:

КЛ>Кто-нибудь так делает?



Я и глава комитета по С++ так делаем

здесь

Только там более advanced версия с дополнительными бонусами.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Я делаю вот так
От: Small  
Дата: 23.04.06 11:58
Оценка:
Я делаю вот так

// библиотека
template <typename T, typename T::EnumType initialValue>
struct EnumHolder : public T
{
    typedef typename T::EnumType EnumType;

    EnumHolder(IN EnumType value = initialValue)
    {
        this->enumValue_ = value;
    }

    EnumHolder(IN const EnumHolder &rhs)
    {
        this->enumValue_ = rhs.enumValue_;
    }

    EnumHolder &operator=(IN const EnumHolder &rhs)
    {
        this->enumValue_ = rhs.enumValue_;

        return *this;
    }

    EnumHolder &operator=(IN const EnumType value)
    {
        this->enumValue_ = value;
        return *this;
    }

    bool operator==(IN const EnumType value) const
    {
        return this->enumValue_ == value;
    }

    bool operator!=(IN const EnumType value) const 
    { 
        return !(*this == value); 
    }

    /// Оператор приведения типа к типу int, чтобы работал switch
    operator int () const { return (int)this->enumValue_; }

private:        

    EnumType enumValue_;
};

//------------------------------------------------------------
// использование

struct NumbersHelper
{
    enum EnumType { Zero, One, Two, Three};
};

// типизированный enum
typedef EnumHolder<NumbersHelper, NumbersHelper::Zero> Numbers;
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.