Задать вопрос
grey42
@grey42

Возможна ли инициализация const-строки не в конструкторе?

Такой вопрос.

У меня есть некий класс со строковым полем (unsigned char* str). Это поле инициализируется не в конструкторе, а в одном из методов класса. Хотелось бы сделать поле (unsigned char* const), чтобы при вызове его get-функции был можно было получить указатель на данную строку, но не давать возможность изменять данные, которые были записаны при инициализации.


Существует ли какой-нибудь способ это сделать малой кровью? Если все оставлять как есть, то компилятор ругается на то, что инициализации при объявлении и в конструкторе нет. Если добавить ее в конструктор (str = NULL), то затем, соответственно, данные менять будет уже невозможно.


Плюс к тому, есть такая ремарка, инициализация происходит следующим образом:


В методе получается указатель на TCHAR*, который затем преобразуется к char*, который явно кастуется в unsigned char*. Получив указатель на данную строку (она временная и имеет смысл только в рамках инициализатора), вызывается str = new [*длина строки*]; а затем memcpy копирует одно в другое. Таким образом, происходит двойное присвоение, сначала str = new, затем memcpy(str,...). Можно ли прямо здесь умереть с мечтой иметь константные данные?


P.S. std::string не используется намеренно. Но если других вариантов нет, замена на него возможна, но желательно, чтобы get-метод все равно возвращал unsigned char* const.


Заранее спасибо за помощь.
  • Вопрос задан
  • 4070 просмотров
Подписаться 2 Оценить 1 комментарий
Ответ пользователя Владислав К ответам на вопрос (5)
Wyrd
@Wyrd
Архитектор
>> Таким образом, происходит двойное присвоение, сначала str = new, затем memcpy(str,...).
никакого двойного присваивания не происходит

str = new unsigned char[size];

только выделяет память и запоминает, где эта память выделена, сама память не инициализируется.

копирование данных происходит внутри memcpy.

справедливости ради, если у вас typeof( str ) == typeof( usigned const char * ), то вы не сможете вызвать memcpy без приведения типа, т.к. у вас указатель на неизменяемые данные.

вам надо:

class A
{
private:
unsigned const char *str;
A(): str( nullptr ) // можно и не инициализировать в принципе, если уверены,
// что не будете читать его до инициализации
{
}
init(… )
{
unsigned char *ptr = new unsigned char[size];
memcpy( ptr,… );
str = ptr; // сами данные вы тут не меняете, только указатель на данные
}
usigned const char *get() const{ return str; }
};
Ответ написан
Комментировать