Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наследование от контейнера STL. Хорошо? Плохо? Почему? 
V
    Опции темы
andrew_121
Дата 25.5.2009, 00:38 (ссылка) |  (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Опять сабж.

Для работы со строками приходится пользоваться алгоритмами. Надоело постоянно вписывать бегины/энды.
Написал свой класс наследник std::string. Знаю что прямое наследование от STL контейнеров не лучшая идея.

Интересует Ваше мнение. Хорошо? Плохо? Почему?

Спасибо!


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Earnest
Дата 25.5.2009, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Гуру считают, что плохо. Вообще наследование от конкретных классов плохо.
В основном, вопросы поддержки. Со временем функциональность расползается (как в базовом классе, если он конкретный, так и в производном), проект теряет четкость, существенные изменения становится трудно вносить... Как раз в этом смысле более безопасно наследование от стандартных классов (т.к. они не меняются). Но не кошерно. Лучше уж обертку сочинить.

Но, ИМХО, иногда, если аккуратно и локально, то можно... 
Кстати, твоя аргументация (зачем тебе наследоваться от string, begin\end не нравятся) как-то неубедительна. Во-первых, у строки куча своих алгоритмов, во вторых, стандартные алгоритмы все через begin\end работают - чего разнобой вносить.... И т.д.



--------------------
...
PM   Вверх
mrbrooks
Дата 25.5.2009, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 2
Всего: 306



Цитата(andrew_121 @  25.5.2009,  00:38 Найти цитируемый пост)
Интересует Ваше мнение. Хорошо? Плохо? Почему?

зачем?
PM MAIL   Вверх
andrew_121
Дата 25.5.2009, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(Earnest @  25.5.2009,  08:15 Найти цитируемый пост)
Кстати, твоя аргументация (зачем тебе наследоваться от string, begin\end не нравятся) как-то неубедительна. Во-первых, у строки куча своих алгоритмов

Не достаточно. Просто есть необходимость кое-что добавить/заменить/изменить.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
mes
Дата 25.5.2009, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(andrew_121 @  24.5.2009,  23:38 Найти цитируемый пост)
Написал свой класс наследник std::string. Знаю что прямое наследование от STL контейнеров не лучшая идея.


Не будет полиморфного удаления, так как базовый деструктор не виртуальный.

Цитата(andrew_121 @  24.5.2009,  23:38 Найти цитируемый пост)
Для работы со строками приходится пользоваться алгоритмами. Надоело постоянно вписывать бегины/энды.

а сделать набор функций оберток над алгоритмами ?


Цитата(andrew_121 @  24.5.2009,  23:38 Найти цитируемый пост)
Интересует Ваше мнение. Хорошо? Плохо? Почему?

Имхо, плохо (но для общего случая.. чтоб сказать конкретно, надо видеть, чего Вы написали.)

Это сообщение отредактировал(а) mes - 25.5.2009, 08:51


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 25.5.2009, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(andrew_121 @  25.5.2009,  08:49 Найти цитируемый пост)
Не достаточно. Просто есть необходимость кое-что добавить/заменить/изменить. 

Почитайте Саттера - особенно главу - Ослабленная монолитность std::string. В нем и так до хрена функций а вы еще хотите добавить smile 

Классы СТЛ не писали в расчете не наследование. Открыто наследовать классы не предназначенные для этого - неправильно (мое лично мнение).
Закрытое наследование - вполне приемлемо.

Это сообщение отредактировал(а) azesmcar - 25.5.2009, 09:22
PM   Вверх
Alek86
Дата 25.5.2009, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(mes @  25.5.2009,  08:51 Найти цитируемый пост)
а сделать набор функций оберток над алгоритмами ?

а заюзать, наконец, буст? в частности, "Boost String Algorithms Library";)

andrew_121, или буст или напиши враппер, что будет делать то, что тебе нужно


--------------------
user posted image    user posted image
PM MAIL   Вверх
Earnest
Дата 25.5.2009, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Или просто набор глобальных функций, которые будут принимать строку. Это лучше, чем наследовать класс.


--------------------
...
PM   Вверх
andrew_121
Дата 25.5.2009, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(mes @  25.5.2009,  08:51 Найти цитируемый пост)
Не будет полиморфного удаления, так как базовый деструктор не виртуальный.

Да, и в правду. Не подумал об этом.


Цитата(mes @  25.5.2009,  08:51 Найти цитируемый пост)
а сделать набор функций оберток над алгоритмами ?

Тогда лучше boost::string_algo заюзать.


Цитата(mes @  25.5.2009,  08:51 Найти цитируемый пост)
Имхо, плохо (но для общего случая.. чтоб сказать конкретно, надо видеть, чего Вы написали.)

Код


#ifndef __LSTRING_H__
#define __LSTRING_H__

#include <string>
#include <vector>
#include <algorithm>

#include "lstringlist.h"

/***************************************************************************/

class LString:public std::string {
public:
    LString():std::string() {}
    LString(const char* s):std::string(s) {}
    LString(const std::string& s):std::string(s) {}
    virtual ~LString() {}
    /**/
    LString& operator() (iterator b, iterator e) {
        resize(e-b);
        std::copy(b, e, begin());
        return *this;
    }
    LString& operator() (const_iterator b, const_iterator e) {
        resize(e-b);
        std::copy(b, e, begin());
        return *this;
    }
    /**/
    LString& operator= (value_type* it) {
        size_type len = strlen(it);
        resize(len);
        std::copy(it, it+len, begin());
        return *this;
    }
    LString& operator= (const value_type* it) {
        size_type len = strlen(it);
        resize(len);
        std::copy(it, it+len, begin());
        return *this;
    }
    /**/
    bool operator! () const { return length() == 0; }
    /**/
    int find(value_type c) const {
        return pos(c);
    }
    int find(value_type c, int p) const {
        return pos(c, p);
    }
    int find(const value_type* c) const {
        return pos(c);
    }
    int find(const value_type* c, int p) const {
        return pos(c, p);
    }
    /**/
    int pos(value_type c) const {
        const_iterator it = std::find(begin(), end(), c);
        if ( it == end() ) return -1;
        return it - begin();
    }
    int pos(value_type c, int p) const {
        const_iterator it = std::find(begin() + p, end(), c);
        if ( it == end() ) return -1;
        return it - begin();
    }
    int pos(const value_type* c) const {
        const_iterator it = std::search(begin(), end(), c, c+strlen(c));
        if ( it == end() ) return -1;
        return it - begin();
    }
    int pos(const value_type* c, int p) const {
        const_iterator it = std::search(begin() + p, end(), c, c+strlen(c));
        if ( it == end() ) return -1;
        return it - begin();
    }
    /**/
    bool contains(value_type c) const {
        return pos(c) != -1;
    }
    bool contains(value_type* c) const {
        return pos(c) != -1;
    }
    bool contains(const LString& s) const {
        return pos(s.data()) != -1;
    }
    /**/
    bool is_empty()                    const { return length() == 0; }
    operator const value_type*    () const    { return data();            }
    operator value_type*            ()            { return (char*)data();    }
    /**/
    LString mid(int b, int n = -1) const {
        int len = (n == -1) ? length()-b : n;
        return substr(b, len);
    }
    LString left( int count ) const {
        return mid( 0, count );
    }
    LString right( size_type count ) const {
        if ( count > length() )
            count = length();
        return mid( length() - count, count );
    }
    /**/
    LStringList split(value_type c) const {
        LStringList final;
        int j = 0;
        int i = find(c, j);
        int l = length();

        while ( i != -1 ) {
            if ( i > j && i <= l )
                final << mid(j, i - j);
            j = i + 1;
            i = find(c, j);
        }

        if ( mid(j, l-j+1).length() > 0 )
            final << mid(j, l-j+1);

        return final;
    }

    void replace(value_type c1, value_type c2) {
        if ( c1 == c2 ) return;
        iterator p = begin();
        while ( p < end() ) {
            p = std::find(p, end(), c1);
            if ( p == end() ) return;
            if ( c2 == '\0' ) {
                iterator f = std::copy(p+1, end(), p);
                *f = '\0';
                resize( std::find(begin(), end(), 0) - begin() );
            } else {
                *p = c2;
            }
            p++;
        }
    }
};

/***************************************************************************/

#endif // __LSTRING_H__


Код


#ifndef __LSTRINGLIST_H__
#define __LSTRINGLIST_H__

#include <vector>

class LString;
/***************************************************************************/

class LStringList:public std::vector<LString> {
public:
   LStringList():std::vector<LString>() {}
   LStringList( const LString& o ):std::vector<LString>() { add(o); }
   LStringList( const LStringList&);
    virtual ~LStringList() { clear(); }
   /**/
   LStringList& operator<< ( const LString&);
   LStringList& operator+= ( const LString&);
   LStringList& operator+= ( const LStringList&);
   void add( const LString&);
   bool contains(const LString&) const;

    LString join(const LString&) const;
   LStringList grep(const LString& str);
   
   bool is_empty() const { return empty(); }
};

/***************************************************************************/

#endif // __LSTRINGLIST_H__





--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
mes
Дата 25.5.2009, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



ну и зачем Вам наследовать интерфейс класса std::string ?  ради метода length () и нескольких тайпдефоф ?
не легче ли просто открыть к нему доступ, через метод  ? (например так std::string& LString::std(); и для const).
как минимум избавитесь от путаницы методов.








--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0781 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.