Должен ли мы вернуть указатель на вектор из функции? [Дубликат]

Если таблицы cols и значения являются переменными, то существует два способа:

С двойными кавычками "" полный запрос:

$query = "INSERT INTO $table_name (id, $col1, $col2)
                 VALUES (NULL, '$val1', '$val2')";

Или

 $query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.")
               VALUES (NULL, '".$val1."', '".$val2."')";

С одинарными кавычками '':

$query = 'INSERT INTO '.$table_name.' (id, '.$col1.', '.$col2.')
             VALUES (NULL, '.$val1.', '.$val2.')';

Использовать обратные тики ``, когда имя столбца / значения похоже на зарезервированное ключевое слово MySQL.

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

`table_name`. `column_name` & lt; - Примечание: исключить . из обратных тиков.

142
задан Shoe 30 April 2014 в 10:39
поделиться

7 ответов

Я не хочу возвращать скопированное значение, потому что оно неэффективно

Докажите его.

Посмотрите на RVO и NRVO, а в C + + 0x move-semantics. В большинстве случаев в C ++ 03 параметр out - это просто хороший способ сделать ваш код уродливым, а в C ++ 0x на самом деле вы будете болеть сами, используя параметр out.

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


Тем не менее, если вы мертвы для написания подобным образом, вы, вероятно, захотите сделать параметр out. Это позволяет избежать динамического распределения памяти, что является более безопасным и, как правило, быстрее. Это требует, чтобы у вас был какой-то способ построить объект до вызова функции, что не всегда имеет смысл для всех объектов.

Если вы хотите использовать динамическое распределение, то самое меньшее, что можно сделать, это поместите его в умный указатель. (Это должно быть сделано все время в любом случае). Тогда вы не беспокоитесь о том, чтобы удалять что-либо, вещи безопасны для исключений и т. Д. Единственная проблема - это, скорее всего, медленнее, чем возвращение по значению в любом случае!

96
ответ дан GManNickG 1 September 2018 в 10:15
поделиться
38
ответ дан Amir Rachum 1 September 2018 в 10:15
поделиться

Вы пытались использовать интеллектуальные указатели (если Thing действительно большой и тяжелый объект), например auto_ptr:


std::auto_ptr<Thing> calculateThing()
{
  std::auto_ptr<Thing> thing(new Thing);
  // .. some calculations
  return thing;
}


// ...
{
  std::auto_ptr<Thing> thing = calculateThing();
  // working with thing

  // auto_ptr frees thing 
}
11
ответ дан demetrios 1 September 2018 в 10:15
поделиться

Просто верните такой объект:

Thing calculateThing() 
{
   Thing thing();
   // do calculations and modify thing
   return thing;
}

Это вызовет конструктор копирования в Things, так что вы можете захотеть выполнить свою собственную реализацию. Например:

Thing(const Thing& aThing) {}

Это может быть немного медленнее, но это может быть не проблема.

Обновить

Компилятор, вероятно, оптимизирует вызов конструктора копирования, поэтому никаких дополнительных накладных расходов не будет. (Как отмечалось в комментарии).

13
ответ дан Destructor 1 September 2018 в 10:15
поделиться

Одним быстрым способом определить, будет ли вызван конструктор копирования, является добавление журнала в конструктор копирования вашего класса:

MyClass::MyClass(const MyClass &other)
{
    std::cout << "Copy constructor was called" << std::endl;
}

MyClass someFunction()
{
    MyClass dummy;
    return dummy;
}

Вызов someFunction; число строк, которые вы получили, будет меняться от 0, 1 и 2. Если вы его не получили, ваш компилятор оптимизировал возвращаемое значение (что разрешено делать). Если вы получите, не получите 0, а ваш конструктор копий смехотворно дорог , тогда будет искать альтернативные способы возврата экземпляров из ваших функций.

7
ответ дан dreamlax 1 September 2018 в 10:15
поделиться

Я уверен, что эксперт на C ++ придет с лучшим ответом, но лично мне нравится второй подход. Использование умных указателей помогает с проблемой забывания delete, и, как вы говорите, он выглядит более чистым, чем создание объекта перед рукой (и его все еще нужно удалить, если вы хотите выделить его в кучу).

0
ответ дан EMP 1 September 2018 в 10:15
поделиться

Во-первых, у вас есть ошибка в коде, вы имеете в виду Thing *thing(new Thing()); и только return thing;.

  • Используйте shared_ptr<Thing>. Deref это как это было указателем. Он будет удален для вас, когда последняя ссылка на Thing, содержащаяся, выходит за рамки.
  • Первое решение очень распространено в наивных библиотеках. Он имеет некоторую производительность и синтаксические накладные расходы, избегая его, если это возможно
  • Используйте второе решение, только если вы можете гарантировать, что не будут исключены исключения или когда производительность будет абсолютно критической (вы будете взаимодействовать с C или сборкой до этого даже становится актуальным).
1
ответ дан Matt Joiner 1 September 2018 в 10:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: