Я плохо знаком с программированием на C++, но у меня есть опыт в Java. Мне нужно руководство о том, как передать объекты функциям в C++.
Я должен передать указатели, ссылки или неуказательные и нессылочные значения? Я помню в Java нет таких проблем, так как мы передаем просто переменную, которая содержит ссылку на объекты.
Было бы замечательно, если Вы могли бы также объяснить, где использовать каждую из тех опций.
Передайте на значение , за исключением случаев, когда
const
ссылку , const
lvalue reference, const
или нет). Прохождение по указателю практически никогда не рекомендуется. Опциональные параметры лучше всего выразить в виде std::optional
(boost::optional
для более старых версий std libs), а наложение псевдонима прекрасно выполняется по ссылке. Семантика движения
C++11 делает передачу и возврат по значению намного более привлекательным даже для сложных объектов.
Передача аргументов по const
reference, за исключением тех случаев, когда
const
NULL
/0
/nullptr
; применить предыдущее правило, чтобы определить, следует ли передавать указатель на аргумент const
(здесь "pass by value" называется "pass by copy", потому что передача по значению всегда создает копию в C++03)
Есть еще кое-что, но эти несколько правил для новичков заставят вас зайти достаточно далеко.
Существуют некоторые различия в призвании конвенций в C ++ и Java. В C ++ используются технически говорящие только два конвенция: Pass-Value и Pass-Restain, причем некоторая литература, включающая в себя третью конвенцию Pass-By-Powner (которая фактически проходит по значению типа указателя). Кроме того, вы можете добавить Const-Ness к типу аргумента, повышая семантику.
Пасс по ссылке
Прохождение по ссылке означает, что функция будет концептуально примет экземпляр объекта и не копию ее. Ссылка концептуально псевдоним объектам, который использовался в контексте вызова и не может быть нулевым. Все операции, выполняемые внутри функции, применяются к объекту вне функции. Эта конвенция недоступна в Java или C.
pass по значению (и pass-by-указателю)
Компилятор будет генерировать копию объекта в контексте вызова и использовать эту копию внутри функции. Все операции, выполняемые внутри функции, выполняются к копии, а не внешним элементом. Это Конвенция для примитивных типов в Java.
Специальная версия ее передает указатель (адрес - объект) в функцию. Функция получает указатель, и любая и все операции, применяемые к самому указателю, применяются к копии (указатель), с другой стороны, операции, применяемые к разделушению указателя, будут применяться к экземпляру объекта в этом месте памяти, поэтому функция может иметь побочные эффекты. Эффект использования Pass-Value of указателя на объект позволит внутреннюю функцию изменять внешние значения, как с помощью передачи Pass-Researt, и также позволит дополнительным значениям (пройти нулевой указатель).
Это конвенция, используемая в C, когда функция должна модифицировать внешнюю переменную, а Конвенцию, используемую в Java со ссылками: ссылка скопирована, но указанный объект одинаково: изменения в ссылке / указатель Не видно вне функции, но изменения в заостренной памяти.
Добавление Const в уравнение
в C ++. Вы можете назначить постоянные значения на объекты при определении переменных, указателей и ссылок на разных уровнях. Вы можете объявить постоянную переменную, вы можете объявить ссылку на постоянный экземпляр, и вы можете определить все указатели на постоянные объекты, постоянные указатели на муравьевые объекты и постоянные указатели к постоянным элементам. И наоборот в Java, вы можете определить только один уровень константы (окончательное ключевое слово): что из переменной (экземпляра для примитивных типов, ссылка на ссылочные типы), но вы не можете определить ссылку на неизменный элемент (если сам класс не неизменный).
Это широко используется в C ++, вызывающих конвенции. Когда объекты маленькие, вы можете пройти объект по значению. Компилятор будет генерировать копию, но эта копия не является дорогой операцией. Для любого другого типа, если функция не изменит объект, вы можете передавать ссылку на постоянный экземпляр (обычно называемый постоянной ссылкой) типа. Это не будет скопировать объект, но передавать его в функцию. Но в то же время компилятор гарантирует, что объект не изменяется внутри функции.
Правила большого пальца
Это некоторые основные правила для следующих правил:
. Есть другие маленькие отклонения от этих правил Первый из которых занимается право собственности на объект. Когда объект динамически выделяется с новым, он должен быть отделен удалением (или его версий []). Объект или функция, отвечающая за разрушение объекта, считается владельцем ресурса. Когда динамически выделенный объект создается в кусочке кода, но владение передается на другой элемент, он обычно делается с помощью проходной семантики, или, по возможности с помощью смарт-указателей.
Боковая заметка
Важно настаивать в важности разницы между ссылками C ++ и Java. В ссылках C ++ концептуально экземпляру объекта, а не доступа к нему. Самый простой пример реализует функцию свопа:
// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
Type tmp = a;
a = b;
b = tmp;
}
int main() {
Type a, b;
Type old_a = a, old_b = b;
swap( a, b );
assert( a == old_b );
assert( b == old_a );
}
Функция свопа выше изменяется как его аргументы благодаря использованию ссылок. Ближайший код в Java:
public class C {
// ...
public static void swap( C a, C b ) {
C tmp = a;
a = b;
b = tmp;
}
public static void main( String args[] ) {
C a = new C();
C b = new C();
C old_a = a;
C old_b = b;
swap( a, b );
// a and b remain unchanged a==old_a, and b==old_b
}
}
Версия кода Java изменит копии ссылок внутри, но не будет изменять фактические объекты снаружи. Ссылки Java представляют собой указатели C без арифметики указателя, который передается по значению в функции.