Чи добре використовувати std
Я регулярно маю суперечки з колегами на тему чи варто повсюдно використовувати std :: string. або таки треба реалізовувати свій клас для рядків.
Одне з питань - це питання якості самої реалізації std :: string. Забавно, що більшість людей, яких я просив накидати прототип класу для рядків, більш менш ефективного з точки зору роботи з пам'яттю, писали приблизно наступне:
Ясно, що при такій реалізації оператора присвоювання рядок в плані займаної пам'яті буде тільки рости. Це зроблено спеціально.
Практично ніхто відразу не думав про необхідність наявності операції переміщення, наприклад swap. Чомусь наявність конструктора копіювання і оператора присвоювання вважається достатнім.
Що відповісти на це питання раз і назавжди для себе самого, я написав тестову програму. Це програма сортує масив з довгих рядків. Рядки представлені чотирма способами: об'єкт std :: string. покажчик на std :: string. об'єкт самопального класу String (див. вище) і покажчик на String.
За попередніми очевидним оцінками робота через покажчик повинна бути максимально ефективна, так як в даному випадку при переміщенні об'єктів фізично std :: sort () переставляє тільки покажчики, а не самі об'єкти.
А ось при роботі безпосередньо з об'єктами буде цікаво порівняти, наскільки банальна реалізації рядки поступатиметься std :: string.
Видно, що версії з покажчиками відпрацювали приблизно однаково швидко, а ось при роботі з об'єктами std :: string обігнав самопальную реалізацію в 4 рази - 203 мс проти 891 мс.
Нескладно зрозуміти, чому це так. std :: sort () для перестановки елементів використовує шаблонну функцію std :: swap (). яка для std :: string реалізована так, щоб робити перестановку без фізичного копіювання даних. А для String все відбувається банально через конструктор копіювання і оператор присвоювання.
Загалом, для себе я виніс, що не треба городити свій город, так як в більшості випадків std :: string вирішує всі проблеми. Але виникає питання - як додавати в std :: string свою функціональність? Наприклад, пошук слів.
Проблема в тому, що у std :: string деструктор оголошений як невіртуальний (може це зроблено з міркувань ефективності), а спадкування від класу з невіртуальну деструктором в C ++ є не найправильнішою витівкою.
While we could make a member function to return length, it is better to make it a global friend function. If we do that, we will be able eventually to define the same function to work on built-in arrays and achieve greater uniformity of design. I made size into a member function in STL in an attempt to please the standard committee. I knew that begin, end and size should be global functions but was not willing to risk another fight with the committee.
Він вважає, що глобальна шаблонна функція length () - це правильніше, ніж length () як член класу. Якби не комітет стандартизації - так воно і було б в STL.
Отже, підсумовуючи сказане, не варто не довіряти std :: string. Для більшості завдань цей клас вирішує всі проблеми. Якщо треба додати функціональність - це треба робити через реалізацію шаблонного алгоритму.
Є зауваження або протести? Докладайте.