Re[2]: Моя первая реализация String
От: Lorenzo_LAMAS  
Дата: 08.07.04 13:36
Оценка: +3
_AK>
_AK>nvString a,b,c;
_AK>a+b=c;
_AK>


Предлагаю попробовать такое
std::string a, b, c;
a + c = b;


_>>Моя первая реализация String


_AK>Лучше чтобы она была бы ещё и последней.


Зачем так? Человек попросил указать ошибки, а ему — такие гадости.
Of course, the code must be complete enough to compile and link.
Re[4]: Моя первая реализация String
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 08.07.04 16:34
Оценка: +3
Здравствуйте, _AK_, Вы писали:

_AK>Здравствуйте, Lorenzo_LAMAS, Вы писали:


_AK>>>
_AK>>>nvString a,b,c;
_AK>>>a+b=c;
_AK>>>


L_L>>Предлагаю попробовать такое

L_L>>
L_L>>std::string a, b, c;
L_L>>a + c = b;
L_L>>


_>>>>Моя первая реализация String


_AK>>>Лучше чтобы она была бы ещё и последней.


L_L>>Зачем так? Человек попросил указать ошибки, а ему — такие гадости.


_AK>не гадости, а намёк: std::string...


Надо сначала свои шишки набить. имхо.
HgLab: Mercurial Server and Repository Management for Windows
Re[9]: Моя первая реализация String
От: ioni Россия  
Дата: 08.07.04 15:44
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:


А>Дело не в ошибке. Стандартом не определяется что delete на 0 не реагирует. Каждый реализует по своему разумению. Просто в последнее время стало считатся хорошим тоном проверять в операторе delete на 0. В более ранних версиях компиляторов проверки небыло.


5.3.5.2
.... if the value of the operand of delete is the null pointer the operation has no effect
Re[3]: Моя первая реализация String
От: SergeMukhin Россия  
Дата: 08.07.04 14:10
Оценка: +1
Здравствуйте, AndrewJD, Вы писали:

AJD>Здравствуйте, SergeMukhin, Вы писали:


SM>>Здравствуйте, roma_k, Вы писали:


_>>>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!


SM>>3. вместо int надо size_t (где речь идет о длинах)

AJD>Почему ?

например strlen выдает size_t, и так для переносимости.

SM>>5. где поддержка UNICODE?

AJD>Должна быть?

да, и класс должен быть шаблном.
---
С уважением,
Сергей Мухин
Re[8]: Моя первая реализация String
От: Аноним  
Дата: 08.07.04 15:28
Оценка: -1
Здравствуйте, SergeMukhin, Вы писали:

SM>Здравствуйте, kaa_t, Вы писали:



__>>>Можно писать и так :

__>>>
__>>>delete p;
__>>>p=NULL;
__>>>


_>>При таком варианте приходится полагатся, на разработчиков компиляторов,а также на разработчиков библиотек.


SM>ну вы даете!

SM>1. причем тут компилятор?
SM>2. неужели могут быть сомнения, что при реализации delete разработчики допустят такую ошибку?

Дело не в ошибке. Стандартом не определяется что delete на 0 не реагирует. Каждый реализует по своему разумению. Просто в последнее время стало считатся хорошим тоном проверять в операторе delete на 0. В более ранних версиях компиляторов проверки небыло.

SM>что значит устарело? так вроде всегда было!

Было, будет и нужно так делать. Просто теперь можно проверку не ставить (правда предворительно проверив свой компилятор)
Re[9]: Моя первая реализация String
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 08.07.04 15:42
Оценка: +1
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, Нахлобуч, Вы писали:


ВН>>>Я про это и говорю. Какой у тебя синтаксис operator [] ? Если char &operator [] ( int k ), то надо перечитать мой предыдущий пост. Если ты хочешь прокси-объект возвращать, то действительно можно обойтись без mutable. Только в этом случае на каждый чих ты будешь пересчитывать длину строки. А если она тебе никогда не понадобится?


Н>>Ну я про прокси-класс и писал. А пересчет (если он вообще потребуется) займет всего-то ничего:

ВН> 1. Где прокси-класс? В примере не прокси-класс.
Я писал, что можно использовать прокси-класс.

ВН> 2. Все-равно пересчет — лишние инструкции для процессора. +Затраты на прокси.

Это да.
HgLab: Mercurial Server and Repository Management for Windows
Моя первая реализация String
От: roma_k Украина  
Дата: 08.07.04 11:11
Оценка:
Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!
// Заголовок 
class nvString
{
public:
    // constructor
    nvString();

    // Construct a string from a char pointer
    nvString(const char* inStr);

    // Copy-constructor
    nvString(const nvString& inStr);

    // destructor
    virtual ~nvString();

    // Type cast to char pointer
    inline operator const char *() const
    { return m_buffer; }

    // Indexing operator
    inline char operator[](int i) const
    { return m_buffer[i]; }

    // Char pointer atribuition operator
    nvString& operator=(const char* inStr);

    // Atribuition operator
    nvString& operator=(const nvString& inStr);

    // Concatenation operator with a char pointer
    nvString operator+(const char* inStr);

    // Concatenation operator
    nvString operator+(const nvString& inStr);

    // Self-concatenation operator with a char pointer
    void operator+=(const char* inStr);
    
    // Self-concatenation operator
    void operator+=(const nvString& inStr);

    void Clear(void);
    
    // Find a sub-string in the string
    inline int Find(const char *str) const
    { 
        char *pos=strstr(m_buffer,str);
        if (pos == 0)
            return -1;
        return (int)(pos-m_buffer); 
    }

    // Find the first occurrence of a character in the string
    inline int Find(char c) const
    { 
        char *pos = strchr(m_buffer,c);
        if (pos == 0)
            return -1;
        return (int)(pos-m_buffer); 
    }

    // Find the last occurrence of a character in the string
    inline int FindLast(char c) const
    {
        char *pos = strrchr(m_buffer,c);
        if (pos == 0)
            return -1;
        return (int)(pos-m_buffer); 
    }

    // Change the 'i'-th character of the string
    inline void SetChar(int i,char c)
    { 
        if (i < (int)strlen(m_buffer)) 
            m_buffer[i] = c;
    }

    // Crop the first 'n' characters of the string
    inline void CropBegin(int n)
    { 
        if (n < (int)strlen(m_buffer))
        {
            strcpy(m_buffer,&m_buffer[n]);
        }
    }

    // equal compare operator
    inline int operator==(const char *str) const 
    { return strcmp(m_buffer,str)==0; }

    inline int operator!=(const char *str) const 
    { return strcmp(m_buffer,str)!=0; }

    inline int operator>(const char *str) const 
    { return strcmp(m_buffer,str)>0; }

    inline int operator<(const char *str) const 
    { return strcmp(m_buffer,str)<0; }

    inline int operator>=(const char *str) const 
    { return strcmp(m_buffer,str)>=0; }

    inline int operator<=(const char *str) const 
    { return strcmp(m_buffer,str)<=0; }

    // Compare with a char pointer
    inline int Compare(const char *str) const
    { return strcmp(m_buffer,str); }

    // Compare the first 'n' characters of the string with a char pointer
    inline int Compare(const char *str,int n) const
    { return strncmp(m_buffer,str,n); }

    // Compare with a char pointer, case-insensitive flavour
    inline int CompareNoCase(const char *str) const
    { return stricmp(m_buffer,str); }

    // Change all characters to lower-case
    inline void ToLower()
    { strlwr(m_buffer); }

    // Change all characters to upper-case
    inline void ToUpper()
    { strupr(m_buffer); }

    // Return the length of the string in bytes
    inline int Length() const
    { return (int)strlen(m_buffer); }

private:
    char *m_buffer;
};

// тело
char* StrDuplicate(const char *str)
{
    char *strRet = new char[strlen(str)+1];
    assert(strRet);
    strcpy(strRet, str);
    return strRet;
}

nvString::nvString()
{
    m_buffer = StrDuplicate("");
}

nvString::nvString(const char* inStr)
{
    assert(inStr);
    m_buffer = StrDuplicate(inStr);
}

nvString::nvString(const nvString& inStr)
{
    assert(inStr.m_buffer);

    m_buffer = StrDuplicate(inStr.m_buffer);
}

nvString::~nvString()
{
    SafeArrayDelete(m_buffer);
}

void nvString::Clear(void)
{
  operator=("");
}

nvString& nvString::operator=(const char* inStr)
{
    assert(inStr);

    char *str = StrDuplicate(inStr);
    SafeArrayDelete(m_buffer);
    m_buffer = str;

    return *this;
}

nvString& nvString::operator=(const nvString& inStr)
{
    assert(inStr.m_buffer);

    char *str = StrDuplicate(inStr.m_buffer);
    SafeArrayDelete(m_buffer);
    m_buffer = str;

    return *this;
}

nvString nvString::operator+(const char* inStr)
{
    assert(inStr);

    nvString ret;

    int    len = (int)strlen(m_buffer) + (int)strlen(inStr)+1;
    char *str = StrDuplicate(m_buffer);
    assert(str);

    SafeArrayDelete(ret.m_buffer);

    ret.m_buffer = new char [len];
    assert(ret.m_buffer);

    strcpy(ret.m_buffer, str);
    strcat(ret.m_buffer, inStr);
    SafeArrayDelete(str);

    return ret;
}

nvString nvString::operator+(const nvString& inStr)
{
    assert(inStr.m_buffer);

    nvString ret;

    int    len = (int)strlen(m_buffer) + (int)strlen(inStr.m_buffer)+1;
    char *str = StrDuplicate(m_buffer);
    assert(str);

    SafeArrayDelete(ret.m_buffer);

    ret.m_buffer = new char [len];
    assert(ret.m_buffer);

    strcpy(ret.m_buffer, str);
    strcat(ret.m_buffer, inStr.m_buffer);
    SafeArrayDelete(str);

    return ret;
}

void nvString::operator+=(const char* inStr)
{
    assert(inStr);

    int    len = (int)strlen(m_buffer) + (int)strlen(inStr)+1;
    char *str = StrDuplicate(inStr);
    char *strOld = StrDuplicate(m_buffer);

    SafeArrayDelete(m_buffer);
    m_buffer = new char[len];
    strcpy(m_buffer,strOld);
    strcat(m_buffer,inStr);
    SafeArrayDelete(str);
    SafeArrayDelete(strOld);
}

void nvString::operator+=(const nvString& inStr)
{
    assert(inStr.m_buffer);

    int    len = (int)strlen(m_buffer) + (int)strlen(inStr.m_buffer)+1;
    char *str = StrDuplicate(inStr.m_buffer);
    char *strOld = StrDuplicate(m_buffer);

    SafeArrayDelete(m_buffer);
    m_buffer = new char[len];
    strcpy(m_buffer,strOld);
    strcat(m_buffer,inStr.m_buffer);
    SafeArrayDelete(str);
    SafeArrayDelete(strOld);
}

Исправлено форматирование. Пожалуйста, не забывайте пользоваться тегами [c] ... [/c], [code] ... [/code] и т.п. для выделения фрагментов кода. -- ПК.
With best regards, roma_k.
Re: Моя первая реализация String
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 08.07.04 11:29
Оценка:
Здравствуйте, roma_k, Вы писали:

_>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!

_>// Заголовок
class nvString
{
public:
    // constructor
    nvString();

    // Construct a string from a char pointer
    nvString(const char* inStr);

    // Copy-constructor
    nvString(const nvString& inStr);

    // destructor
    virtual ~nvString();

    // Type cast to char pointer
    inline operator const char *() const
    { return m_buffer; }
    
    // Indexing operator
    inline char operator[](int i) const
    { return m_buffer[i]; }
    
    // Сделай еще что-нибудь типа "GetAt()" с проверкой индекса

    // Char pointer atribuition operator
    const nvString& operator=(const char* inStr);

    // Atribuition operator
    const nvString& operator=(const nvString& inStr);

    // Такие два оператора, имхо, лучше делать глобальными
    // Concatenation operator with a char pointer
    nvString operator+(const char* inStr);

    // Concatenation operator
    nvString operator+(const nvString& inStr);

    // Self-concatenation operator with a char pointer
    const nvString& operator+=(const char* inStr);
    
    // Self-concatenation operator
    const nvString& operator+=(const nvString& inStr);

    void Clear(void);
    
    // Find a sub-string in the string
    inline int Find(const char *str) const
    { 
        char *pos=strstr(m_buffer,str);
        if (pos == 0)
            return -1;
        return (int)(pos-m_buffer); 
    }

    // Find the first occurrence of a character in the string
    inline int Find(char c) const
    { 
        char *pos = strchr(m_buffer,c);
        if (pos == 0)
            return -1;
        return (int)(pos-m_buffer); 
    }

    // Find the last occurrence of a character in the string
    inline int FindLast(char c) const
    {
        char *pos = strrchr(m_buffer,c);
        if (pos == 0)
            return -1;
        return (int)(pos-m_buffer); 
    }

    // Change the 'i'-th character of the string
    // Удобнее было бы еще и через индексирование сделать. Через прокси-класс :)
    inline void SetChar(int i,char c)
    { 
        if (i < (int)strlen(m_buffer)) 
            m_buffer[i] = c;
    }

    // Crop the first 'n' characters of the string
    inline void CropBegin(int n)
    { 
        if (n < (int)strlen(m_buffer))
        {
            strcpy(m_buffer,&m_buffer[n]);
        }
    }
    
    // А сравнения с nvString?

    // equal compare operator    
    inline int operator==(const char *str) const 
    { return strcmp(m_buffer,str)==0; }

    inline int operator!=(const char *str) const 
    { return strcmp(m_buffer,str)!=0; }

    inline int operator>(const char *str) const 
    { return strcmp(m_buffer,str)>0; }

    inline int operator<(const char *str) const 
    { return strcmp(m_buffer,str)<0; }

    inline int operator>=(const char *str) const 
    { return strcmp(m_buffer,str)>=0; }

    inline int operator<=(const char *str) const 
    { return strcmp(m_buffer,str)<=0; }

    // Compare with a char pointer
    inline int Compare(const char *str) const
    { return strcmp(m_buffer,str); }

    // Compare the first 'n' characters of the string with a char pointer
    inline int Compare(const char *str,int n) const
    { return strncmp(m_buffer,str,n); }

    // Compare with a char pointer, case-insensitive flavour
    inline int CompareNoCase(const char *str) const
    { return stricmp(m_buffer,str); }

    // Change all characters to lower-case
    inline void ToLower()
    { strlwr(m_buffer); }

    // Change all characters to upper-case
    inline void ToUpper()
    { strupr(m_buffer); }

    // Return the length of the string in bytes
    // Это кэшировать надо
    inline int Length() const
    { return m_nLength; }

private:
    char *m_buffer;
    int m_nLength;
};
HgLab: Mercurial Server and Repository Management for Windows
Re: Моя первая реализация String
От: SergeMukhin Россия  
Дата: 08.07.04 11:30
Оценка:
Здравствуйте, roma_k, Вы писали:

_>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!


1. чем этот String лучше других?
2. почему С текст не форматирован?
3. вместо int надо size_t (где речь идет о длинах)
4. почему StrDuplicate не в классе?
5. где поддержка UNICODE?
6. в += используется strcpy/strcat вместо memcpy*2
и вообще там получается ТРИ раза new, и пять копирований строк!!! не многовато ли?

и т.д. и т.п.

вообщем на троечку. базовые знания языка есть.
---
С уважением,
Сергей Мухин
Re: Моя первая реализация String
От: _AK_ Россия  
Дата: 08.07.04 11:47
Оценка:
Здравствуйте, roma_k, Вы писали:

_>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!


Сходу найдено следующее. Если поискать чуть тщательней, то несомневаюсь что список можно расширить в два-три раза.

1) Лишние опреаторы (с учётом того что конструктор не-explicit).
2) Постоянное использование в качестве индекса типа int.
3) До глубины души умиляет SafeArrayDelete (явно внутри что-то типа: if (p) {delete p;})
4) exception-safety и не пахнет (new то может швынуть bad_alloc — не стоит забывать про это)
5) Класс позволяет писать следующие загадочные вещи:

nvString a,b,c;
a+b=c;


_>Моя первая реализация String


Лучше чтобы она была бы ещё и последней.
Re: Моя первая реализация String
От: denisku Россия  
Дата: 08.07.04 11:53
Оценка:
Здравствуйте, roma_k, Вы писали:

[...]

1) почему деструктор виртуальный? у тебя нет ни одного виртуального метода.
2) лучше хранить длину строки в отдельной переменной, а не вызывать каждый раз strlen(). Очень неэффективно получается..
3) оператор индексирования сделан так, что с помощью него не изменить содержимого строки. То есть написать что-то типа такого не получится:
my_str[0] = 'a';

ИМХО, не очень удобно. Я бы предложил такую реализацию:
// Indexing operator
inline char operator[](const size_t ind) const { 
 return m_buffer[i];
}

inline char& operator[](const size_t ind) { 
 return m_buffer[i];
}

4) предлагаю функцию StrDuplicate() сделать статической и private класса.
5) не нашел определения функции SafeArrayDelete()...
6) оператор+= реализован очень уж неэффективно.. каждый раз вызывается функция StrDuplicate() [и не раз вызывается], а он выделяет память через new... в общем, задумайся над этим куском кода
7) еще я бы добавил конструктор, который принимает 2 параметра: символ и длину строки. Чтобы вся строка состояла из этих символов.
8) operator+= должен возвращать ссылку на объект твоего класса(а не void!). У тебя нельзя записать так:
my_str2 = my_str1 += "aaaaa";

9) добавь operator+=(const char).
10) добавь operator+(const char).
11) добавь operator=(const char).
12) может память выделять немного заранее? то есть сначала выделяем какой-то кусок памяти, его используем. Если не хватает памяти для какой-то операции, выделяем новый кусок памяти(например, в 2 раза больше, чем старый), копируем туда содержимое и освобождаем память под старый буффер. хоть и памяти будет жрать больше, работать будет быстрее. так реализовано(по аналогии) в std::string.
3) удачи
Извините за потраченный траффик..
Re[2]: Моя первая реализация String
От: LIS  
Дата: 08.07.04 13:29
Оценка:
Здравствуйте, _AK_, Вы писали:

_AK>3) До глубины души умиляет SafeArrayDelete (явно внутри что-то типа: if (p) {delete p;})


А можно спросить — чем плохо использование такой конструкции?
Re[3]: Моя первая реализация String
От: _nn_  
Дата: 08.07.04 13:31
Оценка:
Здравствуйте, LIS, Вы писали:

LIS>Здравствуйте, _AK_, Вы писали:


_AK>>3) До глубины души умиляет SafeArrayDelete (явно внутри что-то типа: if (p) {delete p;})


LIS>А можно спросить — чем плохо использование такой конструкции?

Это не плохо, просто смысла в проверке никакого.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Моя первая реализация String
От: LIS  
Дата: 08.07.04 13:38
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, LIS, Вы писали:


LIS>>Здравствуйте, _AK_, Вы писали:


_AK>>>3) До глубины души умиляет SafeArrayDelete (явно внутри что-то типа: if (p) {delete p;})


LIS>>А можно спросить — чем плохо использование такой конструкции?

__>Это не плохо, просто смысла в проверке никакого.

А как же проверить что объект был удален до этого?
Я вот делаю так:

#define DELETE_P if (p) { delete p; p = NULL; }


и потом когда еще раз пытаюсь удалить объект, то никаких exception не валится (хотя обработку все равно надо ставить).
Re[5]: Моя первая реализация String
От: SergeMukhin Россия  
Дата: 08.07.04 13:45
Оценка:
Здравствуйте, LIS, Вы писали:


LIS>
LIS>#define DELETE_P if (p) { delete p; p = NULL; }
LIS>


LIS>и потом когда еще раз пытаюсь удалить объект, то никаких exception не валится (хотя обработку все равно надо ставить).


достаточно {delete p; p = NULL;}

delete для NULL ничего не делает.
---
С уважением,
Сергей Мухин
Re[5]: Моя первая реализация String
От: _nn_  
Дата: 08.07.04 13:45
Оценка:
Здравствуйте, LIS, Вы писали:

LIS>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, LIS, Вы писали:


LIS>>>Здравствуйте, _AK_, Вы писали:


_AK>>>>3) До глубины души умиляет SafeArrayDelete (явно внутри что-то типа: if (p) {delete p;})


LIS>>>А можно спросить — чем плохо использование такой конструкции?

__>>Это не плохо, просто смысла в проверке никакого.

LIS>А как же проверить что объект был удален до этого?

LIS>Я вот делаю так:

LIS>
LIS>#define DELETE_P if (p) { delete p; p = NULL; }
LIS>


Можно писать и так :
delete p;
p=NULL;


LIS>и потом когда еще раз пытаюсь удалить объект, то никаких exception не валится (хотя обработку все равно надо ставить).
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Моя первая реализация String
От: Вадим Никулин Россия Здесь
Дата: 08.07.04 14:02
Оценка:
Здравствуйте, roma_k, Вы писали:

_>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!

_> // Type cast to char pointer
_> inline operator const char *() const
_> { return m_buffer; }

_> // Indexing operator

_> inline char operator[](int i) const
_> { return m_buffer[i]; }

Наличие двух таких операторов одновременно часто приводит компиляторы в тупик. Александреску
Автор(ы): Андрей Александреску

В книге изложена новая технология программирования, представляющая собой сплав обобщенного программирования, метапрограммирования шаблонов и объектно- ориентированного программирования на С++. Настраиваемые компоненты, созданные автором, высоко подняли уровень абстракции, наделив язык С++ чертами языка спецификации проектирования, сохранив всю его мощь и выразительность. В книге изложены способы реализации основных шаблонов проектирования. Разработанные компоненты воплощены в библиотеке Loki, которую можно загрузить с Web-страницы автора. Книга предназначена для опытных программистов на С++.
рекомендует избавиться от operator const char *. Он разбирает похожий пример, но для указателей.
Еще я не могу оценить смысл виртуальности деструктора.
Re[2]: Моя первая реализация String
От: Вадим Никулин Россия Здесь
Дата: 08.07.04 14:03
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

Н>Здравствуйте, roma_k, Вы писали:


_>>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!

_>>// Заголовок
Н>
Н>class nvString
Н>{
Н>public:

Н>    // Return the length of the string in bytes
Н>    // Это кэшировать надо
Н>    inline int Length() const
Н>    { return m_nLength; }

Н>private:
Н>    int m_nLength;            // Может mutable ?
Н>};
Н>
Re[2]: Моя первая реализация String
От: AndrewJD США  
Дата: 08.07.04 14:06
Оценка:
Здравствуйте, SergeMukhin, Вы писали:

SM>Здравствуйте, roma_k, Вы писали:


_>>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!


SM>3. вместо int надо size_t (где речь идет о длинах)

Почему ?

SM>5. где поддержка UNICODE?

Должна быть?
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[2]: Моя первая реализация String
От: Lorenzo_LAMAS  
Дата: 08.07.04 14:09
Оценка:
ВН>Наличие двух таких операторов одновременно часто приводит компиляторы в тупик.

Да, особенно если типа параметра у оператора [] не int, а std::size_t :

#include <cstddef>
class String
{
public:
   operator const char * ()const;
   char & operator[](std::size_t);
   char operator[](std::size_t)const;
};
///
String s;
///
char c = s[0];
Of course, the code must be complete enough to compile and link.
Re[3]: Моя первая реализация String
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 08.07.04 14:22
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, Нахлобуч, Вы писали:


Н>>Здравствуйте, roma_k, Вы писали:


_>>>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!

_>>>// Заголовок
Н>>
Н>>class nvString
Н>>{
Н>>public:

Н>>    // Return the length of the string in bytes
Н>>    // Это кэшировать надо
Н>>    inline int Length() const
Н>>    { return m_nLength; }

Н>>private:
Н>>    int m_nLength;            // Может mutable ?
Н>>};
Н>>


А смысл? Там же нет константных функций, которые чего-то с длиной делают.
HgLab: Mercurial Server and Repository Management for Windows
Re[6]: Моя первая реализация String
От: kaa_t Россия  
Дата: 08.07.04 14:24
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Можно писать и так :

__>
__>delete p;
__>p=NULL;
__>


При таком варианте приходится полагатся, на разработчиков компиляторов,а также на разработчиков библиотек.

LIS>>
LIS>>#define DELETE_P if (p) { delete p; p = NULL; }
LIS>>


Так надежней. Хотя и устарело...
Re[7]: Моя первая реализация String
От: SergeMukhin Россия  
Дата: 08.07.04 14:28
Оценка:
Здравствуйте, kaa_t, Вы писали:


__>>Можно писать и так :

__>>
__>>delete p;
__>>p=NULL;
__>>


_>При таком варианте приходится полагатся, на разработчиков компиляторов,а также на разработчиков библиотек.


ну вы даете!
1. причем тут компилятор?
2. неужели могут быть сомнения, что при реализации delete разработчики допустят такую ошибку?

_>Так надежней. Хотя и устарело...



что значит устарело? так вроде всегда было!
---
С уважением,
Сергей Мухин
Re[7]: Моя первая реализация String
От: _nn_  
Дата: 08.07.04 14:35
Оценка:
Здравствуйте, kaa_t, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


__>>Можно писать и так :

__>>
__>>delete p;
__>>p=NULL;
__>>


_>При таком варианте приходится полагатся, на разработчиков компиляторов,а также на разработчиков библиотек.


LIS>>>
LIS>>>#define DELETE_P if (p) { delete p; p = NULL; }
LIS>>>


_>Так надежней. Хотя и устарело...

Что имеется вииду под словом "надежней" ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Моя первая реализация String
От: Вадим Никулин Россия Здесь
Дата: 08.07.04 14:51
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

_>>>>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!

_>>>>// Заголовок
Н>>>
Н>>>class nvString
Н>>>{
Н>>>public:

Н>>>    // Return the length of the string in bytes
Н>>>    // Это кэшировать надо
Н>>>    inline int Length() const
Н>>>    { return m_nLength; }

Н>>>private:
Н>>>    int m_nLength;            // Может mutable ?
Н>>>};
Н>>>


Н>А смысл? Там же нет константных функций, которые чего-то с длиной делают.


При любом изменении объекта m_nLength должно меняться. Например, написав
   str[5] = 0;

у нас длина будет изменена. Но в операторе мы еще не знаем, как изменится длина, поэтому там мы можем написать
   m_nLength = -1;

а метод Length переписать так:
   int Length() const
   {
      if( m_nLength==-1 )
         m_nLength = strlen( ... );
      return m_nLength;
   }

Вот в этом случае mutable и потребуется.
Re[5]: Моя первая реализация String
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 08.07.04 15:04
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>При любом изменении объекта m_nLength должно меняться. Например, написав

ВН>
ВН>   str[5] = 0;
ВН>

ВН>у нас длина будет изменена. Но в операторе мы еще не знаем, как изменится длина, поэтому там мы можем написать
ВН>
ВН>   m_nLength = -1;
ВН>

ВН>а метод Length переписать так:
ВН>
ВН>   int Length() const
ВН>   {
ВН>      if( m_nLength==-1 )
ВН>         m_nLength = strlen( ... );
ВН>      return m_nLength;
ВН>   }
ВН>

ВН>Вот в этом случае mutable и потребуется.

Тода лучше ввести operator [] который смог бы отличить чтение (константный) от записи (неконстантный оператор) и изменять m_nLength (если требуется) в последнем.
HgLab: Mercurial Server and Repository Management for Windows
Re[6]: Моя первая реализация String
От: Вадим Никулин Россия Здесь
Дата: 08.07.04 15:18
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

Н>Тода лучше ввести operator [] который смог бы отличить чтение (константный) от записи (неконстантный оператор) и изменять m_nLength (если требуется) в последнем.


Я про это и говорю. Какой у тебя синтаксис operator [] ? Если char &operator [] ( int k ), то надо перечитать мой предыдущий пост. Если ты хочешь прокси-объект возвращать, то действительно можно обойтись без mutable. Только в этом случае на каждый чих ты будешь пересчитывать длину строки. А если она тебе никогда не понадобится?
Re[7]: Моя первая реализация String
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 08.07.04 15:25
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, Нахлобуч, Вы писали:


Н>>Тода лучше ввести operator [] который смог бы отличить чтение (константный) от записи (неконстантный оператор) и изменять m_nLength (если требуется) в последнем.


ВН>Я про это и говорю. Какой у тебя синтаксис operator [] ? Если char &operator [] ( int k ), то надо перечитать мой предыдущий пост. Если ты хочешь прокси-объект возвращать, то действительно можно обойтись без mutable. Только в этом случае на каждый чих ты будешь пересчитывать длину строки. А если она тебе никогда не понадобится?


Ну я про прокси-класс и писал. А пересчет (если он вообще потребуется) займет всего-то ничего:

class string
{
    // ...
    char& operator [] (size_t n)
    {
        
    }
    
};
HgLab: Mercurial Server and Repository Management for Windows
Re[8]: Моя первая реализация String
От: Вадим Никулин Россия Здесь
Дата: 08.07.04 15:36
Оценка:
Здравствуйте, Нахлобуч, Вы писали:

ВН>>Я про это и говорю. Какой у тебя синтаксис operator [] ? Если char &operator [] ( int k ), то надо перечитать мой предыдущий пост. Если ты хочешь прокси-объект возвращать, то действительно можно обойтись без mutable. Только в этом случае на каждый чих ты будешь пересчитывать длину строки. А если она тебе никогда не понадобится?


Н>Ну я про прокси-класс и писал. А пересчет (если он вообще потребуется) займет всего-то ничего:

1. Где прокси-класс? В примере не прокси-класс.
2. Все-равно пересчет — лишние инструкции для процессора. +Затраты на прокси.
Н>
Н>class string
Н>{
Н>    // ...
Н>    char& operator [] (size_t n)
Н>    {
Н>    }
    
Н>};
Н>
Re[8]: Моя первая реализация String
От: kaa_t Россия  
Дата: 08.07.04 15:45
Оценка:
Здравствуйте, _nn_, Вы писали:

LIS>>>>
LIS>>>>#define DELETE_P if (p) { delete p; p = NULL; }
LIS>>>>


_>>Так надежней. Хотя и устарело...

__>Что имеется вииду под словом "надежней" ?

Вопрос переносимости.
Re[9]: Моя первая реализация String
От: _nn_  
Дата: 08.07.04 15:47
Оценка:
Здравствуйте, kaa_t, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


LIS>>>>>
LIS>>>>>#define DELETE_P if (p) { delete p; p = NULL; }
LIS>>>>>


_>>>Так надежней. Хотя и устарело...

__>>Что имеется вииду под словом "надежней" ?

_>Вопрос переносимости.

В чем имено проблема с переносимостью ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: Моя первая реализация String
От: kaa_t Россия  
Дата: 08.07.04 16:03
Оценка:
Здравствуйте, ioni, Вы писали:

I>Здравствуйте, Аноним, Вы писали:



А>>Дело не в ошибке. Стандартом не определяется что delete на 0 не реагирует. Каждый реализует по своему разумению. Просто в последнее время стало считатся хорошим тоном проверять в операторе delete на 0. В более ранних версиях компиляторов проверки небыло.


I>5.3.5.2

I>.... if the value of the operand of delete is the null pointer the operation has no effect

Не все компиляторы подерживают стандарт. Стандарт в окончательной редакции был вупущен в начале 1998г + пару лет на доработку компиляторов.
Re[11]: Моя первая реализация String
От: ioni Россия  
Дата: 08.07.04 16:07
Оценка:
Здравствуйте, kaa_t, Вы писали:

А>>>Дело не в ошибке. Стандартом не определяется что delete на 0 не реагирует. Каждый реализует по своему разумению. Просто в последнее время стало считатся хорошим тоном проверять в операторе delete на 0. В более ранних версиях компиляторов проверки небыло.


I>>5.3.5.2

I>>.... if the value of the operand of delete is the null pointer the operation has no effect

_>Не все компиляторы подерживают стандарт. Стандарт в окончательной редакции был вупущен в начале 1998г + пару лет на доработку компиляторов.


ну сейчас уже слава богу 2004
и даже vc6 с этим справляется
Re[3]: Моя первая реализация String
От: _AK_ Россия  
Дата: 08.07.04 16:30
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

_AK>>
_AK>>nvString a,b,c;
_AK>>a+b=c;
_AK>>


L_L>Предлагаю попробовать такое

L_L>
L_L>std::string a, b, c;
L_L>a + c = b;
L_L>


_>>>Моя первая реализация String


_AK>>Лучше чтобы она была бы ещё и последней.


L_L>Зачем так? Человек попросил указать ошибки, а ему — такие гадости.


не гадости, а намёк: std::string...
Re[10]: Моя первая реализация String
От: kaa_t Россия  
Дата: 08.07.04 16:30
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, kaa_t, Вы писали:


_>>Здравствуйте, _nn_, Вы писали:


LIS>>>>>>
LIS>>>>>>#define DELETE_P LIS>>>>>>


_>>>>Так надежней. Хотя и устарело...

__>>>Что имеется вииду под словом "надежней" ?

_>>Вопрос переносимости.

__>В чем имено проблема с переносимостью ?


Kaa>Не все компиляторы подерживают стандарт. Стандарт в окончательной редакции был вупущен в начале 1998г.

С высокой долей вероятности можно утверждать что на компиляторе выпущеном до 1998г, проверки на 0 может не оказаться.
Также никто не может гарантировать, что на N компиляторе N версии выпущеном позднее, будет проверяться указатель (всегда есть вероятность обратного).
Re[11]: Моя первая реализация String
От: _nn_  
Дата: 08.07.04 16:37
Оценка:
Здравствуйте, kaa_t, Вы писали:

_>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, kaa_t, Вы писали:


_>>>Здравствуйте, _nn_, Вы писали:


LIS>>>>>>>
LIS>>>>>>>#define DELETE_P LIS>>>>>>


_>>>>>Так надежней. Хотя и устарело...

__>>>>Что имеется вииду под словом "надежней" ?

_>>>Вопрос переносимости.

__>>В чем имено проблема с переносимостью ?


Kaa>>Не все компиляторы подерживают стандарт. Стандарт в окончательной редакции был вупущен в начале 1998г.

_>С высокой долей вероятности можно утверждать что на компиляторе выпущеном до 1998г, проверки на 0 может не оказаться.
_>Также никто не может гарантировать, что на N компиляторе N версии выпущеном позднее, будет проверяться указатель (всегда есть вероятность обратного).
Полностью согласен, так как реализация не всегда соответсвует стандарту, однако вероятность того что неправильно будет отработанно delete 0 в компиляторе позже 1998 очень мала.

P.S.
На всякий случай можно проверить поведение delete 0 на конкретном компиляторе.
Или пользоватся макросом :
#if // нету соответствия со стандартом
#define DELETE_IF(x) \
 if(x) { delete x; x=0; }
#else // соответствие со стандартом
#define DELETE_IF(x) \
 { delete x; x=0; }
#endif


IMHO смысл в подобных извращениях я не вижу.

P.P.S.
Думаю стоит эту тему закрыть.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Моя первая реализация String
От: folk Россия  
Дата: 08.07.04 21:34
Оценка:
Здравствуйте, roma_k, Вы писали:

_>Оцените пожалуйста, интересны все мои ошибки, особенно в реализации операторов !!!

[]

Когда определяешь функции внутри определения класса, то можно не писать inline, они являются inline по умолчанию.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[9]: Моя первая реализация String
От: Шахтер Интернет  
Дата: 10.07.04 00:41
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, SergeMukhin, Вы писали:


SM>>Здравствуйте, kaa_t, Вы писали:



__>>>>Можно писать и так :

__>>>>
__>>>>delete p;
__>>>>p=NULL;
__>>>>


_>>>При таком варианте приходится полагатся, на разработчиков компиляторов,а также на разработчиков библиотек.


SM>>ну вы даете!

SM>>1. причем тут компилятор?
SM>>2. неужели могут быть сомнения, что при реализации delete разработчики допустят такую ошибку?

А>Дело не в ошибке. Стандартом не определяется что delete на 0 не реагирует.


Неправда.

А>Каждый реализует по своему разумению. Просто в последнее время стало считатся хорошим тоном проверять в операторе delete на 0. В более ранних версиях компиляторов проверки небыло.


Неправда.

SM>>что значит устарело? так вроде всегда было!

А>Было, будет и нужно так делать. Просто теперь можно проверку не ставить (правда предворительно проверив свой компилятор)
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[11]: Моя первая реализация String
От: Шахтер Интернет  
Дата: 10.07.04 01:01
Оценка:
Здравствуйте, kaa_t, Вы писали:

_>Здравствуйте, ioni, Вы писали:


I>>Здравствуйте, Аноним, Вы писали:



А>>>Дело не в ошибке. Стандартом не определяется что delete на 0 не реагирует. Каждый реализует по своему разумению. Просто в последнее время стало считатся хорошим тоном проверять в операторе delete на 0. В более ранних версиях компиляторов проверки небыло.


I>>5.3.5.2

I>>.... if the value of the operand of delete is the null pointer the operation has no effect

_>Не все компиляторы подерживают стандарт. Стандарт в окончательной редакции был вупущен в начале 1998г + пару лет на доработку компиляторов.


Это тоже неправда. Текущий стандарт -- это третья версия языка. Сам язык существует уже очень давно. С самого начала delete не делал ничего с нулевыми указателями.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.