Использование собственного класса строк
От: YourLastSong  
Дата: 15.01.12 19:35
Оценка:
Здравствуйте, уважаемые господа.

Есть реализация собственного класса строк:

class MyString
{
    private:
        size_t length;
        char *str;

    public:
        MyString ();
        MyString (const char *c);
        MyString (const MyString& t);
        ~MyString ();

        MyString& operator= (const MyString& t);
        MyString operator+ (const MyString& t) const;
        MyString operator+ (const char *c) const;
        bool operator== (const MyString& t) const;
        bool operator!= (const MyString& t) const;
        void operator+= (const MyString& t);
        char& operator[] (size_t i);

        char& at (size_t i);
        void get_input (std::istream& in);
        size_t size () const;
        size_t get_length () const;

        friend std::ostream& operator<< (std::ostream& out, const MyString& t);
        friend std::istream& operator>> (std::istream& in, MyString& t);
};

MyString::MyString ()
{
    length = 0;
    str = NULL;
}

MyString::MyString (const char *c)
{
    length = strlen (c) + 1;
    str = new char[length];
    strcpy (str, c);
    str[length-1] = '\0';
}

MyString::MyString (const MyString& t)
{
    length = strlen (t.str) + 1;
    str = new char[length];
    strcpy (str, t.str);
    str[length-1] = '\0';
}

MyString::~MyString ()
{
    if (str != NULL)
    {
        delete[] str;
    }
}

MyString& MyString::operator= (const MyString& t)
{
    length = strlen (t.str) + 1;
    str = new char[length];
    strcpy (str, t.str);
    str[length-1] = '\0';

    return *this;
}

MyString MyString::operator+ (const MyString& t) const
{
    char* newStr = new char[strlen (str) + strlen (t.str) + 1];
    strcpy (newStr, str);
    strcat (newStr, t.str);
    newStr[length-1] = '\0';

    MyString returnObj (newStr);
    delete[] newStr;

    return returnObj;
}

bool MyString::operator== (const MyString& t) const
{
    return (strcmp(str, t.str) == 0);
}

bool MyString::operator!= (const MyString& t) const
{
    return (strcmp(str, t.str) != 0);
}

void MyString::operator+= (const MyString& t)
{
    length = strlen (str) + strlen (t.str) + 1;
    char *newStr = new char[length];
    strcpy (newStr, str);
    strcat (newStr, t.str);
    strcpy (str, newStr);
    str[length-1] = '\0';
    delete[] newStr;
}

char& MyString::operator[] (size_t i)
{
    return str[i];
}

char& MyString::at (size_t i)
{
    if (i >= 0 && i < length)
    {
        return str[i];
    }
}

void MyString::get_input (std::istream& in)
{
    while (true)
    {
        char c = in.get ();

        if (c == '\n')
        {
            break;
        }

        if (length == 0)
        {
            length = 2;
        }
        else
        {
            ++length;
        }

        char* newStr = new char[length];
        if (str != NULL)
        {
            strcpy (newStr, str);
        }
        newStr[length-2] = c;
        newStr[length-1] = '\0';

        delete[] str;

        str = newStr;
    }
}

size_t MyString::size () const
{
    return length;
}

size_t MyString::get_length () const
{
    if (length == 0)
    {
        return 0;
    }
    else
    {
        return (length - 1);
    }
}

std::ostream& operator<< (std::ostream& out, const MyString& t)
{
    out << t.str;
    return out;
}

std::istream& operator>> (std::istream& in, MyString& t)
{
    t.get_input (in);
    return in;
}


Всё ли здесь так, как надо?

Что бы вы предложили добавить сюда и каким образом?

Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?

Заранее благодарю за возможные ответы.
Re: Использование собственного класса строк
От: Abyx Россия  
Дата: 15.01.12 20:02
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Всё ли здесь так, как надо?


оно не скомпилируется
In Zen We Trust
Re: Использование собственного класса строк
От: Анатолий Широков СССР  
Дата: 15.01.12 20:21
Оценка:
А какие примитивные тесты вы реализовали, чтобы проверить работоспобность этого класса?

Я почему задаю вопрос. Возьмем к примеру:
MyString a;
MyString b;
a = b; // ops
MyString c("1");
c = c; // ops
char ch = c.at(100); // как вы, кстати, скомпилировали at?
MyString d("2");
d = c; // memory leak
MyString e("1\02"); // терминирующий ноль в середине строки, как результат много сюрпризов с потерей полезных данных


Из очевидного:
1. оператор == можно выразить через отрицание оператора !=
2. реализация оператора + может быть проще:
return MyString(a)+=b;


До полноценного строкового класса MyString, к сожалению, надо еще расти.

Теперь я хочу задать вопрос вам: зачем прикладному программисту этот сырой класс? Как, правило, прикладное программирование — это сосредоточение на прикладной задаче, вы же предлагаете потенциальным клиентам (прикладным программистам) своего класса еще и море эротического удовольствия. Зачем это?
Re: Использование собственного класса строк
От: о_О
Дата: 15.01.12 20:25
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?

не. худшее, что можно придумать
Re: Использование собственного класса строк
От: _niko_ Россия  
Дата: 15.01.12 20:30
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Есть реализация собственного класса строк:


YLS>

YLS> . . . . . .
YLS>

А зачем изобретать колесо? Что не устраивает в том же std::string — принципиально не хотим использовать STL?


YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?


Весь базовый функционал необходимый при работе со строками есть в std::string, если в конкретном случае чего то нехватает всегда можно воспользоваться:
— наследованием;
— агрегированием.
Писать свой класс с луня смысла не вижу, для такого решения должно быть вразумительное обоснование, а оно есть?
Re: Использование собственного класса строк
От: minorlogic Украина  
Дата: 15.01.12 20:35
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Всё ли здесь так, как надо?


Долго анализировать и читать. Лучше приведите список преимуществ и недостатков по сравнению с std::string.

YLS>Что бы вы предложили добавить сюда и каким образом?




YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?

Не стал, по той же причине по ктоторой не стал бы лопатой есть суп.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: Использование собственного класса строк
От: night beast СССР  
Дата: 15.01.12 21:44
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Есть реализация собственного класса строк:

YLS>Всё ли здесь так, как надо?

все плохо. ( от ручной работы с памятью, до передачи null в strlen и отсутствия константных версий доступа к элементу )

YLS>Что бы вы предложили добавить сюда и каким образом?


переписать.

YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?


в таком виде -- нет.

YLS>Заранее благодарю за возможные ответы.


бесплатный совет.
прежде чем писать, изучи имеющиеся аналоги.
Re: Использование собственного класса строк
От: iriska2  
Дата: 15.01.12 21:54
Оценка:
Нет проверки на присваивание самому себе. А вообще за такие велосипеды надо сильно бить.
Re[2]: Использование собственного класса строк
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 15.01.12 22:40
Оценка: +1
Здравствуйте, _niko_, Вы писали:

__>Весь базовый функционал необходимый при работе со строками есть в std::string, если в конкретном случае чего то нехватает всегда можно воспользоваться:

__> — наследованием;

Наследованием — нельзя. std::string для этого не предназначен.

__> — агрегированием.
Ce n'est que pour vous dire ce que je vous dis.
Re: Использование собственного класса строк
От: vladimir_i СССР  
Дата: 15.01.12 23:08
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Есть реализация собственного класса строк:

YLS>...

Для начала, не поддерживает юникод.

Но главное, нет того, ради чего обычно все и затевается — нет других методов преобразования, кроме конкатенации. А ведь добавлять символы можно не только в конец, но и в начало или в середину. И точно также, подстроки можно вырезать. В строке можно искать/менять подстроки, менять регистр и т.д.
Теоретически, главной фишкой библиотеки может быть особо эффективная реализация конкретных операций.
Re: Использование собственного класса строк
От: landerhigh Пират  
Дата: 16.01.12 00:27
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?


Вопрос неправильный. Правильно поставленный вопрос звучит так "Были ли в вашей практики эпизоды, когда приходилось делать собственную реализацию класса строк и чем это было обусловлено?".

Ответ — был один случай. При старте программы создавалось сто тыщ миллионов коротких строк, которые никогда не изменялись, в операциях конкатенации не участвовали и вообще вели себя как константы, и единственное, что от них остальной программе нужно было, это их константное значение. Но строки создавались динамически на основе данных из XML файла. Поскольку длина большинства строк была в районе трех-четырех символов, оверхед от std::string был, мягко говоря, значительным. std::string заменили на простейшую обертку над char*. Выиграли четверть гигабайта памяти. (Интересная подробность — в том же проекте мы отыграли назад еще столько же, отказавшись в одном месте от shared_ptr).

Я вашем случае, как я понимаю, ответа на вопрос "Зачем вам нужна кустомная строка" не будет. Используйте стандартное решение и не разбрасывайте грабли почем зря.
Re: Использование собственного класса строк
От: jazzer Россия Skype: enerjazzer
Дата: 16.01.12 01:09
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Есть реализация собственного класса строк:


Это хорошо, что она есть, но нет самого главного — обоснования, для чего оно нужно, какие задачи решает, и чем лучше std::string.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Использование собственного класса строк
От: MasterZiv СССР  
Дата: 16.01.12 09:14
Оценка:
On 01/15/2012 11:35 PM, YourLastSong wrote:

> Всё ли здесь так, как надо?


Где-то я это уже видел...
Тебе одного RSDN-а мало было?
Posted via RSDN NNTP Server 2.1 beta
Re: Использование собственного класса строк
От: okman Беларусь https://searchinform.ru/
Дата: 16.01.12 13:47
Оценка: 1 (1)
Здравствуйте, YourLastSong, Вы писали:

YLS>Есть реализация собственного класса строк

YLS>Всё ли здесь так, как надо?

Технически — не совсем.
При беглом осмотре находятся утечки памяти (operator =) и access violation (operator +=).

YLS>Что бы вы предложили добавить сюда и каким образом?


Зависит от задачи. Если для самообразования и общего развития, советую заглянуть внутрь
популярных строковых классов (STL std::string, MFC CString, Qt QString) и посмотреть,
как они устроены.

YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?


Стал бы, но только в том случае, если все остальные решения по каким-либо причинам не подошли.
В противном случае это пустая трата времени.
Re: Использование собственного класса строк
От: Banned by IT  
Дата: 16.01.12 16:36
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Есть реализация собственного класса строк:

Главный вопрос: для чего понадобился свой класс?
Я не утверждаю что "свой класс строк не нужен", я спрашиваю "зачем он понадобился" чтоб ответить что в нём должно быть и как.

YLS>Всё ли здесь так, как надо?

Не зная задач, для которых он делался нельзя ответить на этот вопрос.

YLS>Что бы вы предложили добавить сюда и каким образом?

Всё, что необходимо для решения возлагаемых на него задач.

YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?

Уже давно используем. Есть на то свои причины и задачи.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Использование собственного класса строк
От: cruelbob  
Дата: 24.01.12 21:28
Оценка:
Прочитайте про такую штуку как copy-on-write!
Twitter — http://twitter.com/Cruelbob
Блог — http://cruelbob.blogspot.ru/
Мыло — vlad.kolotvin@gmail.com
Re: Использование собственного класса строк
От: Константин Россия  
Дата: 27.01.12 08:29
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Есть реализация собственного класса строк:

YLS>Всё ли здесь так, как надо?
YLS>Что бы вы предложили добавить сюда и каким образом?

Методологическое
1. Нет тестов для проверки корректности операций. Я бы рекомендовал освоится с какой-нибудь системой unit testing для C++, и проверить, что код работает ожидаемо.
2. Отсутствует документация. Для некоторых операций назначение неочевидно без изучения реализации (at/get_length/get_input)

Интерфейс
1. Отсутствуют move constructor и move assignment operator. В реализациях std::string поддерживающих C++11 они есть
2. Не-explicit конструктор из const char* — очень ответственное решение. Нужно хорошо понимать, что это потенциально опасно (появляется неявное преобразование).
3. Отсутствуют константные версии доступа к элементам строки
4. Неразбериха с функциями size/get_length. Лучше оставить только одну, имеющую понятный смысл: длина строки
5. Я бы исключил функцию get_input
6. operator+ есть const char*, но отсутствует для operator+=
7. Обычно operator += возвращает ссылку на себя
8. Непонятно зачем operator + является членом класса
9. Не хватает функции доступа, проверяющей строку на пустоту
10. Я бы добавил функцию swap для O(1) обмена содержимым строк
11. Не хватает operator < для использования в ассоциативных контейнерах (std::set, std::map, ...)
12. Нет совместимости с алгоритмами STL (не предоставляет итератор по элементам строки). Это осознанно?
13. Функциональность бедновата...

Реализация (то что бросается в глаза)
1. Код часто игнорирует возможность прихода нулевых указателей и объектов с полем str == nullptr
2. Реализацию operator + я бы рекомендовал сделать через operator +=
3. operator = я бы предложил реализовать "каноническим образом" через copy constrcutor & swap
4. В нескольких местах течёт память
5. at реализован некорректно (не скомпилируется). Привычно по std::string, чтобы он кинул исключение в случае доступа за границами массива
6. get_input кошмарно прожорлива O(n^2). Для каждого нового элемента идёт удаление/выделение памяти в цикле.

Мне кажется, что написание строкового класса необходимый элемент для обучения. Предложенный класс в текущем состоянии подходит только для обучения/собеседований. По ходу можно научиться следующему:
— Освоиться с использованием систем unit test для C++
— Понять что такое exception-safe код. Какой "канонический" вид operator= и почему он такой
— Познакомиться с реализацией стандартных строковых классов. Сложное, но полезное упражнение реализовать интерфейс предоставляемый классом std::string
— Освоиться с понятием сложности алгоритмов O(n), O(n^2)
— Познакомится с новыми концепциями из стандарта C++11 (move semantics)
— Понять, что написание классов общего назначения на C++11 сложная вещь, и зачастую лучше пользоваться стандартными классами. Например, после появления C++11 пришлось только перекомпилировать код, чтобы извлечь выгоды от реализации в STL поддерживающим C++11 move semantics.

YLS>Стали бы вы использовать собственный класс строк вместо уже готовых решений наподобие std::string? Если нет, то почему?

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