当你不取消引用时,指针不是一个引用吗?

时间:2010-02-24 14:32:17

标签: c++ pointers reference

当你不取消引用它时,指针不是一个引用吗?

#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 个答案:

答案 0 :(得分:13)

指针和引用类似,但在几个方面有所不同:

  1. 他们有不同的访问语法。如果您有T* aT& b,则分别使用a->memberb.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将使用{{1定义移动语义)。因此,您不能拥有引用数组。 (谢谢AshleysBrain)
  6. 有人可能想知道为什么我们有引用,而不是一直使用指针(比如C)。原因是运营商超载或某些运营商。

    考虑赋值运算符。没有引用的函数语法是什么?如果它是T&&那么我们必须写下这样的内容:

    T* operator=(T* lhs, T rhs)

    基本上,引用允许我们使用l值的函数,而不需要指针引用和解引用语法。

答案 1 :(得分:6)

你有错误的方法 - 可以使用指针实现引用(虽然你通常不应该考虑这一点),但C ++中的指针不是引用。您可能会感到困惑,因为在C中,使用指针传递内容称为“按引用调用”,但这是因为C没有像C ++那样的实际引用。

答案 2 :(得分:4)

  

当指针不是指针时   你不要去引用它吗?

不,指针包含一个被解释为内存地址的值。 (它是否包含实际上是有效内存地址的值是另一个问题)

引用是别名,是引用现有值的另一种方式。

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.

编辑:

  

因为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-&gt; {something}):

bool validate_list(std::list<int>* L1) { ... }

答案 3 :(得分:2)

我会说引用更像是编译器处理指针。

使用常规指针,您可以完全控制参考,您可以重新分配,删除它,反转几位......无论如何。

通过引用,编译器处理指针,并且您将获得一个对象,您不必取消引用它,但它仍然是指向同一对象的指针。

使您的代码能够正常运行

BOOST_CHECK_PREDICATE( validate_list, (*list1) );

但我相信你已经知道了:)

我认为这个问题和答案是一致的 What are the differences between a pointer variable and a reference variable in C++?

答案 4 :(得分:1)

虽然引用通常作为指针实现,但语言将它们视为两个独立的概念。两者之间有一些重要的区别:

  1. 引用必须在初始化时绑定,不能重新绑定以引用不同的对象,而指针可能在不同的时间指向不同的地址。
  2. 指针可能是NULL,但引用必须始终绑定到对象。