Указатель не является просто ссылкой, когда Вы не разыменовываете его?

Указатель не является просто ссылкой, когда Вы не разыменовываете его?

#include "stdafx.h"
#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>


std::list<int>* user_defined_func( ) {
    std::cout << "BEGIN: user_defined_func" << std::endl;
    std::list<int>* l = new std::list<int>;

    l->push_back(8);
    l->push_back(0);

    std::cout << "END: user_defined_func" << std::endl;

    return l;
}


bool validate_list(std::list<int> &L1)
{

   std::cout << "BEGIN: validate_list" << std::endl;

   std::list<int>::iterator it1 = L1.begin();

   for(; it1 != L1.end(); ++it1)
   {
      if(*it1<= 1){

         std::cout << "Validation failed because an item in the list was less than or equal to 1." << std::endl;
         std::cout << "END: validate_list" << std::endl;
         return false;
       }
   }

   std::cout << "Test passed because all of the items in the list were greater than or equal to 1" << std::endl;
   std::cout << "END: validate_list" << std::endl;
  return true;
}

BOOST_AUTO_TEST_SUITE( test )
BOOST_AUTO_TEST_CASE( test )
{
   std::list<int>* list1 = user_defined_func();
   BOOST_CHECK_PREDICATE( validate_list, (list1) );
}
BOOST_AUTO_TEST_SUITE_END()

В строке,

BOOST_CHECK_PREDICATE( validate_list, (list1) ); 

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

5
задан Peter Alexander 24 February 2010 в 14:41
поделиться

5 ответов

Разве указатель не является просто ссылкой, когда вы не отменяете ссылку?

Нет, указатель содержит значение, которое интерпретируется как адрес памяти. (Содержит ли он значение, которое на самом деле является действительным адресом памяти - это другой вопрос)

Ссылка - это псевдоним, другой способ обращения к существующему значению.

int i = 5;
int* p = &i; // The value in p is the address that i is stored at.
int& r = i;  // The value in r is 5, because r is an alias of i.
             //   Whenever you use r, it's as if you typed i, and vice versa.
             //   (In this scope, anyway).

int sum = i + r; // Identical to i + i or r + i or r + r.

Edit:

поскольку list1 является указателем, как мне получить доступ к ссылке...?

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

std::list<int>* list1 = user_defined_func();
std::list<int>& list1ref = *list1;
BOOST_CHECK_PREDICATE( validate_list, list1ref );
delete list1;

Конечно, это можно сократить:

std::list<int>* list1 = user_defined_func();
BOOST_CHECK_PREDICATE( validate_list, *list1 );
delete list1;

Ваша функция проверки может принимать указатель вместо ссылки (не забудьте изменить L1.{something} на L1->{something}):

bool validate_list(std::list<int>* L1) { ... }
4
ответ дан 18 December 2019 в 06:11
поделиться

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

  1. Ссылки должны быть связаны во время инициализации и не могут быть повторно привязаны для ссылки на другой объект, в то время как указатели могут указывать на разные адреса в разное время.
  2. Указатели могут иметь значение NULL , но ссылки всегда должны быть привязаны к объекту.
1
ответ дан 18 December 2019 в 06:11
поделиться

У вас все неправильно - ссылки могут быть реализованы с помощью указателей (хотя обычно об этом не стоит думать), но указатели в C++ не являются ссылками. Возможно, вы запутались, потому что в C передача объектов с помощью указателей называется "вызовом по ссылке", но это потому, что в C нет настоящих ссылок, как в C++.

6
ответ дан 18 December 2019 в 06:11
поделиться

Указатели и ссылки похожи, но по-разному различаются:

  1. У них разный синтаксис доступа. Если у вас есть T * a и T & b , вы получаете доступ к переменным и функциям-членам, используя a-> member и b.member соответственно. .
  2. Указатели не могут ни на что указывать, а ссылки всегда должны указывать на что-то. a = 0 допустимо, но b = 0 или что-то в этом роде - нет.
  3. Указатели могут быть «переустановлены» (т. Е. Указатель может быть изменен), тогда как ссылки - нет. a = & b допустимо, но int c; b = c; нет (однако T & b = c есть - ссылки могут быть установлены только при их инициализации). (Спасибо Mike D.)
  4. Указатели не могут ссылаться на временные, но ссылки const могут.
  5. Указатели могут указывать на другие указатели ( T ** ), но ссылки не могут ссылаться на другие ссылки (т. Е. Не существует такой вещи, как T && , хотя обратите внимание, что C ++ 0x будет использовать T && для определения семантики перемещения). В результате у вас не может быть массивов ссылок. (Спасибо AshleysBrain)

Кто-то может задаться вопросом, почему у нас вообще есть ссылки, а не просто постоянно используются указатели (как в C). Причина в перегрузке операторов или в некоторых операторах.

Рассмотрим оператор присваивания. Каким был бы синтаксис функции без ссылок? Если бы это было T * operator = (T * lhs, T rhs) , тогда нам пришлось бы писать такие вещи, как:

int a(1);
&a = 2;

По сути, ссылки позволяют нам иметь функции l-значений без необходимости указатель ссылки и синтаксис разыменования.

13
ответ дан 18 December 2019 в 06:11
поделиться

Я бы сказал, что ссылка больше похожа на указатель, обрабатываемый компилятором.

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

При использовании ссылки компилятор обрабатывает указатель, и вы получаете объект, который не нужно разыменовывать, но он все еще является указателем на тот же объект.

чтобы ваш код работал, вам нужно сделать

BOOST_CHECK_PREDICATE( validate_list, (*list1) );

но я уверен, что вы уже знаете это :)

Я думаю, что этот вопрос и ответ на него находятся в той же линии В чем разница между переменной-указателем и переменной-ссылкой в C++?

2
ответ дан 18 December 2019 в 06:11
поделиться
Другие вопросы по тегам:

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