1 В чем разница между void DoSomething (const Foo & foo) и void DoSomething(Foo foo)
? Если мы не укажем &, то экземпляр Foo
будет передан по значению (а не по ссылке). Это будет то же самое, что и аргумент const + & in, за исключением отсутствия проверки во время компиляции. Итак, почему использование const + & становится лучшей практикой по сравнению с аргументом без & и const?
В C # объект передается по ссылке, но, похоже, этого нет в C ++.
Есть несколько отличий в порядке важности:
- Если объект
Foo
невозможно скопировать, нужно передать его по ссылке
- Если объект
Foo
является базовым классом, вы должны получить его по ссылке, чтобы пользователи могли вызывать ваши функции с производными классами.
- Значение фактического объекта может измениться, даже если у вас есть ссылка на него
const
.
- Эффективность, копирование типов пользователей может быть дорогостоящим, но компиляторы могут быть достаточно умными, чтобы понять это, так что ...
2 В книге, которую я читаю, сказано, что функции-члены передают неявный параметр по ссылке.
Может ли кто-нибудь дать мне образец неявного параметра и по ссылке? Я знаю, что если мы хотим передать объект по ссылке, нам нужно использовать & (например, Foo (Person & p)), но почему С ++ передает объект по ссылке для неявного параметра? Я читал, что неявный параметр в C ++ похож на Contructor (string str): strMemberVariable (str) {} ...
Под неявным параметром следует понимать this
, то есть сам объект. Он эффективно передается по ссылке, поскольку вы можете изменить его состояние в функции-члене.
Следуя замечанию Konrad
: обратите внимание, что сам this
не передается по ссылке, this
является ссылкой (указателем) на объект, а передается по значению. Вы не можете изменить адрес памяти вашего объекта как хотите;)
3 Является ли массив единственным, который передается по ссылке в C ++?
Это не так. Вы увидите изменения в элементах массива, но сам массив (структура) не изменится.
После замечания FredOverflow
, иллюстрация:
void fun(int* p, size_t size);
int main(int argc, char* argv[])
{
int array[15];
fun(array, 15);
}
Мы не знаем, что делает fun
, он, вероятно, изменит некоторые элементы array
, но каким бы ни было его действие, array
останется массивом из 15 целых чисел: содержимое изменяется, а структура - нет.
В результате для изменения array
нам понадобится еще одно объявление:
void changer(int*& array, size_t& size);
Таким образом, мы можем изменить как содержимое, так и структуру (а также передать новый размер). И, конечно же, мы можем вызывать эту функцию только с массивом, который был размещен динамически.
4 Почему я не могу использовать Foo fInstance в классе Foo?
Потому что это бесконечная рекурсия. Подумайте об этом с точки зрения компилятора и попробуйте угадать размер Foo
. Размер Foo
- это сумма размеров его атрибутов, плюс, возможно, некоторая информация о заполнении и типе. Кроме того, размер объекта должен быть не менее 1
, чтобы его можно было адресовать. Итак, если у Foo
есть Foo
, каков его размер :)?
Обычное решение - использовать умный указатель:
class Foo
{
public:
private:
std::unique_ptr<Foo> mInstance;
};
Поскольку размер указателя не зависит от размера объекта, на который указывает, поэтому здесь не происходит рекурсия :)
person
Matthieu M.
schedule
26.06.2010