Я имею дело с QString, неявным общим классом Qt. Что я понимаю о неявном разделяемом классе, так это то, что при копировании объекта фактические данные не копируются, а копируется только указатель на данные. Он будет копировать только при записи (при вызове неконстантных функций). (Поправьте меня если я ошибаюсь)
Я хочу знать, будет ли следующий код слишком дорогим для использования с неявным разделяемым классом:
// assume I have no control over those functions
QString giveMeAString();
void acceptStringReference(const QString &stringRef);
// I have control over this function
QString replaceSomething(QString input) { // shallow copy here
input.replace("foo", "bar"); // deep copy here
return input; // shallow copy here
}
// will this function expensive to call?
acceptStringReference(replaceSomething(giveMeAString());
Или я должен использовать указатель? Разве функция обходится намного дороже, чем передача указателя QString, как показано ниже (но больше кода)?
void replaceSomething(QString *input) {
input.replace("foo", "bar");
}
QString *stringPtr = new QString(giveMeAString());
replaceSomething(stringPtr);
acceptStringReference(*stringPtr);
delete stringPtr;
Еще 3 строки могут выглядеть меньше, но что, если мне нужно многократно вызывать replaceSomething ()?
Ваш первый пример вполне корректен, в этом случае хорошо подойдет копирование при записи.
Второй пример будет работать точно так же, как и первый. Разница лишь в том, что в первом случае временный объект возвращается giveMeAString()
хранится в стеке, а во втором случае этот объект (stringPtr
) явно создается в куче. Динамическое выделение небольших фрагментов памяти происходит медленно и бессмысленно. Второй пример будет медленнее из-за этого. Внутренняя обработка буферов QString будет одинаковой в обоих случаях.
Как насчет этого?
void replaceSomething(QString *input) {
input->replace("foo", "bar");
}
QString string = giveMeAString();
replaceSomething(&string);
acceptStringReference(string);