#c
#c
Вопрос:
Допустим, у меня есть эта функция
class Entity;
Entityamp; CreateEntity(){
Entity* e = new Entity();
entityVec.emplace_back(e);
return *e;
}
В настоящее время оба приведенных ниже кода будут скомпилированы.
Entity a = CreateEntity();
Entityamp; b = CreateEntity();
Однако я хочу убедиться, что только ссылочная переменная может принимать результат функции. В противном случае код будет иметь много непреднамеренных поведений.
Другими словами, есть ли какой-либо способ Entity a = CreateEntity()
вызвать ошибку, и только Entityamp; b = CreateEntity()
разрешено?
Если нет, есть ли какой-либо способ или шаблон, который может обеспечить его выполнение?
Спасибо.
Комментарии:
1. Можете ли вы объяснить, как ваша функция каким-то образом преобразовала указатель в ссылку?
e
это anEntity *
, так как же ему удалось стать anEntity amp;
?2. Вероятно, они забыли a
*
в теле функции.3. Возможно ли, что вы хотите отключить построение / назначение копирования? Похоже, это может быть то, о чем вы думаете.
4. Ну, вы всегда можете удалить конструктор копирования, однако это предотвратит помещение этих объектов в вектор. Я подозреваю, что это проблема XY, и вы спрашиваете, как предотвратить копирование этих объектов. Если да, то у меня плохие новости: они уже постоянно копируются, поскольку помещаются в вектор. В любом случае, нет никакого способа сделать строго то, что вы просите. C так не работает.
5. @SamVarshavchik В коде OP это указатель , который помещается в вектор, поэтому удаленная копия ctor не будет беспокоить этот конкретный случай.
Ответ №1:
Хотелось бы, чтобы для этого было предупреждение компилятора. Потому что то, к чему вы обращаетесь, является реальной проблемой для производительности, особенно при использовании STL.
Анализ кода Microsoft может быть тем, что вы ищете: https://devblogs.microsoft.com/cppblog/new-safety-rules-in-c-core-check/https://learn.microsoft.com/en-us/cpp/code-quality/c26820?view=vs-2019
Если вы контролируете класс, о копировании которого беспокоитесь, вот возможное решение. Обходной путь — просто удалить конструкторы копирования /operator= . Я написал макрос, который делает именно это:
// Disallow the use of the copy constructor and copy assignment operator for a class:
// Note: prefer to place this in public for better compiler error messages (Scott Meyers Effective C )
#define UTIL_DELETE_COPY_AND_ASSIGN(udt)
udt(const udtamp;) = delete;
udtamp; operator =(const udtamp;) = delete;
class foobar
{
public:
UTIL_DELETE_COPY_AND_ASSIGN(foobar);
}
Если вы все еще хотите сохранить функциональность конструктора копирования / назначения, вы можете просто создать более явную версию этих функций, чтобы пользователи знали, что они получают.
class foobar
{
public:
foobar DeepCopy(); {...}
UTIL_DELETE_COPY_AND_ASSIGN(foobar);
}