Разумно ли использовать неявное преобразование в массив символов или писать методы явного преобразования?

Я пишу строковый класс для строк UTF-8, и я столкнулся с проблемой проектирования.

Я хотел бы, чтобы некоторые из моих методов const char * и const Utf8String & в качестве входных значений. Это сделано для того, чтобы избежать вычисления длины и проверки строки UTF-8, когда пользователь передает Utf8Stringи избежать бесполезного выделения памяти для временного Utf8String когда пользователь передает const char *,

Я тоже хочу перегрузить const char * оператор (эквивалентно string::c_str()) потому что это удобно. Проблема в том, что это создает двусмысленность.

Вот почему строки STL обеспечивают c_str() метод вместо оператора перегрузки const char *?

И что я могу сделать здесь? Держите перегруженный оператор const char * и только одна из двух возможных подписей для моих методов (либо const char * или же const Utf8String &) или удалите const char * перегрузка оператора и сохранение двух возможных сигнатур методов?

0

Решение

Я предлагаю написать два метода вместо использования (const char*) оператор. Это может привести к различным проблемам.

Вопрос в том, как управляется память возвращаемого указателя?

Можно написать фатальный код, например так:

const char* getText() {
YourType x = "text";
return x;
}

Здесь ваш тип разрушен, и, скорее всего, ваш массив символов. Но это хорошо компилируется и выглядит хорошо. Трудно определить проблему в вашем коде.

Использование выделенного метода позволяет вам сделать использование понятным:

class YourType {
public:
const char* createCharArray() const;
const char* accessCharArray() const;
}

Один метод выделит новый массив символов, в то время как другой просто создаст внутреннее временное представление символов, которое уничтожается самим типом.

Другая проблема заключается в использовании конструктора, подобного этому:

class YourType {
public:
YourType(const char *str);
}

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

void printText(const YourType &text) {
}

Позволяет это:

printText("Text");

Но также работает для этого:

void foo(const char* text) {
char *str = new char[strlen(text)+1];
std::strcpy(str, text);
printText(str);
}

Здесь я предлагаю использовать static метод преобразования вместо:

class YourType {
public:
static YourType fromCharArray(const char *str);
}
1

Другие решения

Написание собственного строкового класса очень весело (и хорошее упражнение). Но я обнаружил, что этот стандарт std::string отлично работает на струнах UTF-8.

Прежде чем я полностью уйду от темы, я отвечу на ваши вопросы так: когда сомневаетесь, имитируйте стандартные вещи (т.е. std::string). По крайней мере, две причины, почему это сделать. Первый, эти интерфейсы обычно хорошо разработаны (так как над ними работало много людей с разным опытом). второй, разработчики обычно уже знают, как правильно использовать эти вещи.

Но вернемся к строкам UTF-8. Я не знаю зачем тебе нужна отдельный класс для строк UTF-8 и сколько времени вы потратили на размышления о том, действительно ли вам это нужно (мне интересно узнать причины). Дело в том, что UTF-8 является частью стандарта Unicode, который не так прост. И если вам нужна полнофункциональная строка UTF-8, вы в конечном итоге внедрите приличную часть стандарта Unicode (например, формы нормализации, странные правила использования заглавных букв) (знаете ли вы это по буквам греческого языка Сигма имеет разные правила использования заглавных букв в конце слова?) и т. д.). Я уверен, что вы не хотите этого делать, потому что, если вам это нужно, вероятно, лучше использовать ICU, Qt или какую-то другую библиотеку с достойной поддержкой Unicode.

Итак, если вам нужно просто хранилище для символов Utf-8 с некоторыми utf8_to_encoding(), utf8_from_encoding(), utf8_next_code_point() Я рекомендую придерживаться std::string и предоставить другие функции, которые вам нужны в качестве бесплатных функций. Например:

std::string utf8_from_utf16(const uint16_t *s, size_t len);

Может быть мой другой ответ на аналогичную тему может быть полезным.

0

По вопросам рекламы ammmcru@yandex.ru