предположим, я часто делаю какую-то операцию с std::string, и хотел бы к нему добавить методы.
Можно это сделать так:
struct my_string: public std::string //забудем пока про basic_string<C, T, A>, вопрос про misused
{
//повторяю конструкторы std::string
...
//добавляю свои 'удобные методы'
};
template <class T>
struct my_vector: std::vector<T>
{
};
какие причины есть считать это злом? Нутром чую, что это путь в ад, но пока не вижу конкретных плохих вещей. Едиственное что, вижу проблему когда кто-то захочет вдруг передать std::string в функцию, которая принимает my_string.
Все книжки пишут, естли можете сделать операцию на объектом свободной функцией, а не методом, то лучше методом. Я с этим согласен.
Хотелось бы точно понять, какие грабли есть вот в таком наследовании. (Предположим, что в проекте используется только один такой наследник, и других библиотек, которые так расширили строки, нет)
Собственно — это вторая проблема — когда каждая либа начиная клепать свой такой свой string. предположим, что она одна и основная в проекте.
Перечислите, пожалуйста, как можно больше бяк, почему такое наследование некошерно. ^_^
Спасибо.
PS. Наверное, я не прочитал какую-то книжку. Но протелепатировал себе мысль из неё
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Расскажите, почему наследование здесь 'misused'
Здравствуйте, Июнь, Вы писали:
И>Здравствуйте, _Winnie, Вы писали:
_W>>PS. Наверное, я не прочитал какую-то книжку. Но протелепатировал себе мысль из неё
И>В той книжке было написано, что деструкторы стандартных контейнеров не виртуальны и что наследование — 2-ая по силе зависимость в C++.
Добавлю, что некоторые(Саттер) считают, что если можно метод сделать не членом класса, то лучше его не делать членом класса. Кому как нравится.
Ну и плюс невиртуальность деструкторов. Хотя при осторожном использовании...)
Re[3]: Расскажите, почему наследование здесь 'misused'
Здравствуйте, Константин Ленин, Вы писали:
КЛ>Добавлю, что некоторые(Саттер) считают, что если можно метод сделать не членом класса, то лучше его не делать членом класса. Кому как нравится.
Здравствуйте, Июнь, Вы писали:
И>Здравствуйте, _Winnie, Вы писали:
_W>>PS. Наверное, я не прочитал какую-то книжку. Но протелепатировал себе мысль из неё
И>В той книжке было написано, что деструкторы стандартных контейнеров не виртуальны
Да-да-да. Я как раз собирался завести my_string на хипе, потом откастовать его в std::string*, а потом сделать ему delete. ИМХО, это маловероятно (в основном, первый пункт)
> что наследование — 2-ая по силе зависимость в C++.
Ну, жуть. Расширенный стринг зависит от стандартного. Афигеть.
Можно конкретней, где такое наследование выйдет боком? А не общие слова.
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Расскажите, почему наследование здесь 'misused'
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Константин Ленин, Вы писали:
КЛ>>Добавлю, что некоторые(Саттер) считают, что если можно метод сделать не членом класса, то лучше его не делать членом класса. Кому как нравится.
J>Мейерс. Хотя, может, и Саттер тоже.
Ага, Саттер с ним на пару.
Re: Расскажите, почему наследование здесь 'misused'
!
!
!
!
!
_W>Все книжки пишут, естли можете сделать операцию на объектом свободной функцией, а не методом, то лучше методом. Я с этим согласен.
ИЗВИНИТЕ!
Я хотел написать ровно наобороот — "... то лучше свободной функцией."
!
!
!
!
!
!
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Расскажите, почему наследование здесь 'misused'
Пока ты не будешь добавлять свои data-member (иначе их срежешь ...), все будет ОК.
Но все рекомендует этого не делать ...
Также не делай свои ф-ии виртуальными (т.к. std::basic_string для этго не предназначен).
Лично я использую обычные глобальные ф-ии в своем namespace
(точнее шаблоны, при этом реализацию с явным инстанцированием помещаю в .cpp-файлы ).
Re: Расскажите, почему наследование здесь 'misused'
Здравствуйте, _Winnie, Вы писали:
_W>предположим, я часто делаю какую-то операцию с std::string, и хотел бы к нему добавить методы.
Используй агрегицию, а не наследование;
Агрегируй std::string в my_string, реализуй полную совместимость с std::string (конструктор, оператор присваивания и приведение типа), потом "вытащи" в public секцию все методы std::string;
_W>Да-да-да. Я как раз собирался завести my_string на хипе, потом откастовать его в std::string*, а потом сделать ему delete. ИМХО, это маловероятно (в основном, первый пункт)
Зачем хранить в "хипе" std::string и my_string, если в std::string нет виртуальных функций?
ps: вариант с глобальными функциями в отдельном namespace, на мой взгляд самый предпочтительный;
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[2]: Расскажите, почему наследование здесь 'misused'
Здравствуйте, _Winnie, Вы писали:
_W>Все книжки пишут, естли можете сделать операцию на объектом свободной функцией, а не методом, то лучше свободной функцией.
Имхо, лучше смотреть на предметную область и плясать от нее. Примеры методов, которые не смотря на некоторую избыточность интерфейса, смотрятся вполне органично, легко найти в STL — size() (для вектора), is_empty() и т.д..
Хорошо там, где мы есть! :)
Re[2]: Расскажите, почему наследование здесь 'misused'
Здравствуйте, np9mi7, Вы писали:
N>Здравствуйте, _Winnie, Вы писали:
_W>>предположим, я часто делаю какую-то операцию с std::string, и хотел бы к нему добавить методы.
N>Используй агрегицию, а не наследование;
N>Агрегируй std::string в my_string, реализуй полную совместимость с std::string (конструктор, оператор присваивания и приведение типа), потом "вытащи" в public секцию все методы std::string;
Я правильно понял что ты предлагаешь просто взять все-те функции что есть в std::string и скопипастить их в my_string? _W>>Да-да-да. Я как раз собирался завести my_string на хипе, потом откастовать его в std::string*, а потом сделать ему delete. ИМХО, это маловероятно (в основном, первый пункт)
N>Зачем хранить в "хипе" std::string и my_string, если в std::string нет виртуальных функций?
Насколько я понял, предполагаеться использование переменной как библиотекой _Winnie (которая знает о my_string) так и сторонней библиотекой которая и понятия не имеет о каких-то там my_string'ах..
N>ps: вариант с глобальными функциями в отдельном namespace, на мой взгляд самый предпочтительный;
... либо отдельным классом наподобие StrHelper
"Всё что не убивает нас, делает нас сильнее..."
Re[3]: Расскажите, почему наследование здесь 'misused'
Здравствуйте, Чипсет, Вы писали:
Ч>Я правильно понял что ты предлагаешь просто взять все-те функции что есть в std::string и скопипастить их в my_string?
N>>Зачем хранить в "хипе" std::string и my_string, если в std::string нет виртуальных функций? Ч>Насколько я понял, предполагаеться использование переменной как библиотекой _Winnie (которая знает о my_string) так и сторонней библиотекой которая и понятия не имеет о каких-то там my_string'ах..
Я же говорю — реализуй полную совместимость с std::string (конструктор, оператор присваивания и приведение типа);
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[4]: Расскажите, почему наследование здесь 'misused'
Здравствуйте, np9mi7, Вы писали:
N>Здравствуйте, Чипсет, Вы писали:
Ч>>Я правильно понял что ты предлагаешь просто взять все-те функции что есть в std::string и скопипастить их в my_string?
N>Нет, и имел ввиду это:
А не гемморой ли? N>>>Зачем хранить в "хипе" std::string и my_string, если в std::string нет виртуальных функций? Ч>>Насколько я понял, предполагаеться использование переменной как библиотекой _Winnie (которая знает о my_string) так и сторонней библиотекой которая и понятия не имеет о каких-то там my_string'ах..
N>Я же говорю — реализуй полную совместимость с std::string (конструктор, оператор присваивания и приведение типа);
class A //std::string
{
public:
void bI() {};
};
class B //my_string
{
private:
A _a;
public:
void bI() {
_a.bI(); //гемморой
}
};
//левая функция левой библиотекиvoid foo(A *a)
{
}
//где-то в глубинах кодаvoid bar()
{
B *b = new B();
foo(b); //обломись моя черешня
}
"Всё что не убивает нас, делает нас сильнее..."
Re[2]: Расскажите, почему наследование здесь 'misused'
np9mi7 wrote: > Используй агрегицию, а не наследование; > Агрегируй /*std::string*/ в /*my_string*/, реализуй полную совместимость > с /*std::string*/ (конструктор, оператор присваивания и приведение > типа), потом "вытащи" в /*public*/ секцию все методы /*std::string*/;
Их там около 80.
> Зачем хранить в "хипе" /*std::string*/ и /*my_string*/, если в > /*std::string*/ нет виртуальных функций?
Для быстрой передачи, например. Или из одного потока в другой передать.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re: Расскажите, почему наследование здесь 'misused'
Здравствуйте, _Winnie, Вы писали:
_W>>>PS. Наверное, я не прочитал какую-то книжку. Но протелепатировал себе мысль из неё
... >> что наследование — 2-ая по силе зависимость в C++. _W>Ну, жуть. Расширенный стринг зависит от стандартного. Афигеть.
У стандартной строки стандартный только интерфейс, но не реализация.
Я могу привести пример, когда это будет "афигеть". Если ты пишешь статическую/динамическую библиотеку и твой стринг попадает во внешний интерфейс библиотеки. Библиотека собрана и используется. Потом появляется у этой библиотеки клиент, который собран с обновленной версией std::string...
Если от зависимости избавиться, то проблем не будет.
В данном же случае, даже если ты и захочешь уменьшить зависимость, то если extern для шаблонов не работает (а в той книжке написано, что он вероятнее всего не работает), то придется извращаться: хранить указатель на string + forward typedef declaration.
_W>Можно конкретней, где такое наследование выйдет боком? А не общие слова.
"общие слова" — это попытка записать ту мысль, которую ты "протелепатировал", но не смог сформулировать.
Re: Расскажите, почему наследование здесь 'misused'
Здравствуйте, Cyberax, Вы писали:
>> Используй агрегицию, а не наследование; >> Агрегируй /*std::string*/ в /*my_string*/, реализуй полную совместимость >> с /*std::string*/ (конструктор, оператор присваивания и приведение >> типа), потом "вытащи" в /*public*/ секцию все методы /*std::string*/; C>Их там около 80.
Private наследование + using спасут отца русской демократии.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Расскажите, почему наследование здесь 'misused'