Указатель не является просто ссылкой, когда Вы не разыменовываете его?
#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) );
выше, мне сказали, что я не могу передать указатель на ссылку ожидания функции. Я думал, что указатель (который не был разыменован) был просто адресом (т.е. ссылка). Что я пропускаю здесь?
Разве указатель не является просто ссылкой, когда вы не отменяете ссылку?
Нет, указатель содержит значение, которое интерпретируется как адрес памяти. (Содержит ли он значение, которое на самом деле является действительным адресом памяти - это другой вопрос)
Ссылка - это псевдоним, другой способ обращения к существующему значению.
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) { ... }
Хотя ссылки обычно реализуются как внутренние указатели, язык рассматривает их как две отдельные концепции. Между ними есть некоторые важные различия:
NULL
, но ссылки всегда должны быть привязаны к объекту. У вас все неправильно - ссылки могут быть реализованы с помощью указателей (хотя обычно об этом не стоит думать), но указатели в C++ не являются ссылками. Возможно, вы запутались, потому что в C передача объектов с помощью указателей называется "вызовом по ссылке", но это потому, что в C нет настоящих ссылок, как в C++.
Указатели и ссылки похожи, но по-разному различаются:
T * a
и T & b
, вы получаете доступ к переменным и функциям-членам, используя a-> member
и b.member
соответственно. . a = 0
допустимо, но b = 0
или что-то в этом роде - нет. a = & b
допустимо, но int c; b = c;
нет (однако T & b = c
есть - ссылки могут быть установлены только при их инициализации). (Спасибо Mike D.) const
могут. T **
), но ссылки не могут ссылаться на другие ссылки (т. Е. Не существует такой вещи, как T &&
, хотя обратите внимание, что C ++ 0x будет использовать T &&
для определения семантики перемещения). В результате у вас не может быть массивов ссылок. (Спасибо AshleysBrain) Кто-то может задаться вопросом, почему у нас вообще есть ссылки, а не просто постоянно используются указатели (как в C). Причина в перегрузке операторов или в некоторых операторах.
Рассмотрим оператор присваивания. Каким был бы синтаксис функции без ссылок? Если бы это было T * operator = (T * lhs, T rhs)
, тогда нам пришлось бы писать такие вещи, как:
int a(1);
&a = 2;
По сути, ссылки позволяют нам иметь функции l-значений без необходимости указатель ссылки и синтаксис разыменования.
Я бы сказал, что ссылка больше похожа на указатель, обрабатываемый компилятором.
С обычным указателем у вас есть полный контроль над ссылкой, вы можете переназначить ее, удалить, инвертировать несколько битов... что угодно.
При использовании ссылки компилятор обрабатывает указатель, и вы получаете объект, который не нужно разыменовывать, но он все еще является указателем на тот же объект.
чтобы ваш код работал, вам нужно сделать
BOOST_CHECK_PREDICATE( validate_list, (*list1) );
но я уверен, что вы уже знаете это :)
Я думаю, что этот вопрос и ответ на него находятся в той же линии В чем разница между переменной-указателем и переменной-ссылкой в C++?