(C++) Const-Reference модифициран?


Опитвам се да напиша клас низ, който може да изпълнява повечето от действията на 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

Вмъквам "a" в "a" на позиция 10
"a" (това е масив от символи) вече трябва да има стойност "Розите са Розите са червени".
Вместо това има стойност " Roses are Roses are Roses ".
Може да се наложи да добавя, че самата функция работи добре, просто имам проблем с тази препратка към const...

Мисля, че функцията "вмъкване" също променя подадения параметър, но не би трябвало.
Има ли някакъв начин да предотвратя или поправя това?

Благодаря предварително! Надявам се, че въпросът ми е достатъчно ясен.


person cocoz1    schedule 05.06.2018    source източник
comment
намек: this == &str е вярно, когато извикате a.insert(a, 10)   -  person Frank    schedule 05.06.2018
comment
Благодаря, Франк! :)   -  person cocoz1    schedule 06.06.2018


Отговори (1)


Не можете да модифицирате обект чрез препратка към 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. Това означава, че когато премествате знаци в преразпределения буфер, вие променяте данните, които ще бъдат копирани.

person Miles Budnek    schedule 05.06.2018