1 В чем разница между void DoSomething (const Foo & foo) и void DoSomething(Foo foo)
?Если мы не укажем &, тогда экземпляр Foo
будет передан по значению (не по ссылке).Это будет то же самое, что и аргумент const + & в аргументе, за исключением проверки во время компиляции.Итак, почему использование const + & становится лучшей практикой по сравнению с аргументами без & и const?
В C # передача объекта происходит «по ссылке», но, похоже, его нет в C ++.
Существует несколько различий в порядке важности:
- Если объект
Foo
не может быть скопирован, его необходимо передать по ссылке - Если объект
Foo
является базовым классом, вы должны получить его по ссылке, чтобы пользователи могли вызывать ваши функции с производными классами - Значение фактического объекта может измениться, даже если вы удерживаете
const
ссылку на него - Эффективность, копирование пользовательских типов может быть дорогим, но компиляторы могут быть достаточно умными, чтобы понять это, так что ...
2 В книге, которую я читаю, сказано, что членфункции передают неявный параметр по ссылке ..
Может кто-нибудь дать мне образец неявного параметра и по ссылке?Я знаю, что если мы хотим передать объект по ссылке, нам нужно использовать & (например, Foo (Person & p)), но почему C ++ передает объект по ссылке для неявного параметра?Я читал, что неявный параметр в C ++ похож на Contructor (строка 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;
};
Поскольку размер указателя делаетне зависит от размера объекта, на который указывает объект, поэтому здесь не происходит рекурсия:)