2010-10-14 4 views
0

Можете ли вы привести пример, когда я не могу передать аргумент по ссылке, и мне нужно использовать указатель. Я нашел пример, но я не уверен., когда мне нужно пройти по указателю (а не по ссылке)

Предположим, что у вас есть класс D, полученный из базового класса B. Вам нужен указатель, если вы хотите сделать так:

void function(B* b){...} 
int main{ 
    D* d; 
    function(d); 
} 
+1

Вы можете использовать ссылку в своем примере. – JoshD

+1

Я спросил об эквивалентном вопросе совсем недавно http://stackoverflow.com/questions/3835741/are-reference-and-pointer-equal-with-regards-to-polymorphism – pm100

ответ

6

Единственный раз, когда вы не можете использовать ссылку и должны использовать указатель, если вы позволяете понятие «без аргумента», передавая пустой указатель.

Однако вы можете использовать указатели в качестве аргументов, когда вы фактически сохраняете указатель на все, что было передано. Большинство разработчиков C++ заметят, что вы не используете ссылку и уделяете особое внимание тому, что говорит ваша документация.

+0

Можно было бы утверждать, что вы даже тогда не нуждаетесь * указатель, если вы пишете объект с нулевым состоянием. Но что бы это ни было. –

+0

Да, но не все объекты имеют значение NULL, особенно когда вы используете RAII :-) –

+0

@ Джун Диблинг: Я не поклонник концепции Nullable (по крайней мере, встроенный), я предпочитаю «boost :: optional» 'hook, чтобы различать по типу то, что может и не может быть нулевым. –

-1

Единственная причина в том, что вам необходимо передать null. Вы хотите вызвать функцию: «У меня нет одного из них»

6

Если есть руководство по кодированию (например, Google), которое говорит использовать аргументы указателя, то это то, что вы делаете.

В противном случае, только объявить свою собственную функцию с указателем формального аргумента, когда

  • NullPointer является действительным & значимым фактический аргумент, или

  • фактический аргумент наиболее естественно указатель уже, или

  • Вы собираетесь хранить этот указатель где-нибудь.

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

Приветствия & НТН,

+0

+1 для "фактический аргумент является наиболее естественным указателем уже". Очевидным примером является то, что как только вы говорите об итерации, ваша озабоченность связана с тем, где вы находитесь в последовательности, как о каком объекте в последовательности, на которую вы смотрите. Например. http://stackoverflow.com/questions/3909784/how-do-i-find-a-particular-value-in-an-array-and-return-its-index/3909788#3909788. – Brian

+3

Конечно, не используйте Google. Это глупо. – GManNickG

0

Если вы хотите, чтобы отсутствие объекта, вам нужно использовать указатели:.

// This allows DoSomething to receive pointers to NULL, which cannot 
// be done with references 
void DoSomething(Something *pSomething) 
{ 
    if (pSomething) 
    { 
    ... 
    } 
} 

int main() 
{ 
    Something *pSomething=NULL; 

    DoSomething(pSomething); 
} 
+1

вместо функции-long 'if', считать' if (! PSomething) {return; } 'вверху :) –

+0

@Matthieu: Но тогда функция имела бы более одного выхода! ....: P – GManNickG

-2

Я думаю, что если вы хотите передать функцию, вы должны передать ее указателем. Я не вижу, как вы можете передать функцию по ссылке.

Например, возьмем следующую функцию:

#include <iostream> 
#include "math.h" 

void myfun (double value, size_t nofloops, double (*function)(double)) 
    { 
    std::cout << value << std::endl; 
    for (size_t i=0;i<nofloops;++i) 
     { 
     value = function(value); 
     std::cout << value << std::endl; 
     } 
    std::cout << "------------------" << std::endl; 
    } 

void main() 
    { 
    myfun(100,10,sin); 
    myfun(100,10,cos); 
    myfun(100,10,sqrt); 
    } 

Функция в этой небольшой утилиты выполняет заданную функцию несколько раз, принимая результат в качестве входных данных в следующей итерации. Я не вижу, как вы можете передать функцию по ссылке.

+1

-1 для 'void main', который недопустим как в C, так и в C++ (и никогда не был действительным ни на одном из языков). Передача по ссылке: просто замените' (* function) 'на' (& функция) '. Вот и все. :-) Cheers & hth., –

+0

PS: Когда вы передаете функцию по ссылке, вы получаете очень странного зверя (возможно, поэтому вы считали, что это невозможно), * read only reference *. Это не ссылка на const, но вы не можете назначить ее. Поскольку вы не можете назначить функцию, и когда вы думаете о ссылке как просто псевдоним, другое имя, тогда это имеет смысл. –

+0

По-видимому, некоторые старые компиляторы C разрешают «void main». См. Http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/legality-of-void-main.html. – Patrick

1

Другой случай: если вещь вы передаете последний аргумент перед тем переменным числом аргументов:

void fn1(A &a, ...); // Uh oh 
void fn2(A *a, ...); // Good 

Я не знаю, если это требуется по стандарту, или это просто ошибка в реализации компилятор C++, который я использую.

+0

Стандарт только говорит, что переменные аргументы должны быть последним аргументом, или, может быть, должен существовать один предшествующий аргумент. Тип этого аргумента определенно не упоминается. – Puppy

+0

Тип POD прямо перед '...' не требуется с точки зрения объявления или определения функции, но необходимо полезно вернуть эти аргументы с помощью 'va_start()'. 18.7p3: «Если параметр [va_start'] объявлен с помощью функции, массива или ссылочного типа или с типом, который несовместим с типом, который возникает при передаче аргумента, для которого нет параметра, поведение не определено ». – aschepler

+0

Кроме того, в этой ситуации я рекомендую создать неявное преобразование из 'класса A' в структуру POD, которая содержит указатель' A * ', и использовать это как последний именованный аргумент, чтобы пользователи могли вызвать функцию, как если бы Первый тип аргумента был действительно 'A' (или связанная ссылка). – aschepler

1

Как правило, используют указатели на одну из двух вещей:

  • Reassignability - вы не можете пересвязать ссылки.
  • Null указатели - нет такого вещь как пустая ссылка.

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

Смежные вопросы