(C ++) Const-Reference изменен? - PullRequest
0 голосов
/ 05 июня 2018


Я пытаюсь написать строковый класс, который может выполнять большинство действий std :: string.На самом деле, я застрял с моей функцией "вставки".

template <typename T>
class string_base {
public:
... 
/// INSERT FUNCTION 
// len = current string length of *this
// cap = current capacity of this->raw_data
// raw_data = array which holds all characters
// DEF_ALLOC = 8192
// T = type of element (char, wchar_t, char16_t, char32_t), in my case: char
// str.data() returns the char array of the "str" parameter 
// str.length() returns "len" variable of "str"

string_base<T> &insert(const string_base<T> &str, unsigned pos) {
    if (pos > len || !str.length()) return *this;
    unsigned o = len;
    if (cap <= (len += str.length())) {
        cap += (str.length() + DEF_ALLOC);
        raw_data = (T *)realloc(raw_data, (cap * sizeof(T)));
    }
    if (pos) {
        for (unsigned i = o; i >= pos; i--)
            raw_data[i + str.length()] = raw_data[i];
    } else {
        for (unsigned i = o; i > 0; i--)
            raw_data[i + str.length()] = raw_data[i];
        raw_data[str.length()] = raw_data[0];
    }
    for (unsigned i = pos; i < (pos + str.length()); i++)
        raw_data[i] = str.data()[i - pos];
    raw_data[len] = 0x00;
    return *this;
}
private:
T *raw_data;
unsigned len, cap;
};

typedef string_base<char> string;
typedef string_base<wchar_t> wstring;
typedef string_base<char16_t> string16;
typedef string_base<char32_t> string32;

Как мы видим, функция принимает параметр как константную ссылку (которая не может быть изменена функцией, насколько язнаю) Я вызываю функцию следующим образом:

string_base<char> a("Roses are red"); // assign "Roses are red" to a's char array
string_base<char> b("not "); 
//a.insert(b, 10); -> this works correctly  
a.insert(a, 10); // when I pass "a", it does shit

Я вставляю «а» в «а» в позиции 10
«а» (это массив символов) теперь должно иметь значение «РозыРозы покраснели ".
Вместо этого у него есть значение" Розы - это розы - это розы ".
Возможно, мне нужно добавить, что сама функция работает нормально, у меня просто проблема с этой ссылкой const...

Я думаю, что функция "insert" также изменяет переданный параметр, но не должен.
Есть ли способ, как я могу предотвратить или исправить это?

Спасибозаблаговременно!Надеюсь, мой вопрос достаточно ясен.

1 Ответ

0 голосов
/ 05 июня 2018

Вы не можете изменить объект с помощью ссылки на const.Это не значит, что вы не можете изменить этот объект с помощью других ссылок.

В качестве простого примера, следующее совершенно правильно и выдает «100»:

int main() {
    int i = 42;
    int& ri = i;
    const int& cri = i;

    ri = 100;
    std::cout << cri;
}

изменения, сделанные через ri, отражаются через cri, так как оба ссылаются на один и тот же объект.

Ваш вызов a.insert(a, 10) - та же самая ситуация.str и this оба ссылаются на один и тот же объект.Любые изменения, которые вы делаете в текущем объекте, также будут отражены через str.Это означает, что когда вы перемещаете символы в перераспределенном буфере, вы изменяете данные, которые будут скопированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...