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

lee*_*d00 5 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()
Run Code Online (Sandbox Code Playgroud)

在线,

BOOST_CHECK_PREDICATE( validate_list, (list1) ); 
Run Code Online (Sandbox Code Playgroud)

上面,我被告知我无法将指针传递给期望引用的函数.我认为指针(尚未被引用)只是一个地址(即一个引用).我在这里错过了什么?

Pet*_*der 13

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

  1. 它们具有不同的访问语法.如果您有T* aT& 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;
Run Code Online (Sandbox Code Playgroud)

本质上,引用允许我们具有l值的函数,而不需要指针引用和解除引用语法.

  • 实际上,`b =*a`是完全合法的,但它执行副本并且不重置参考.对于`operator =(T*lhs,T rhs)`,编译器可以为你隐藏`&a`(仅在运算符重载的情况下,因为没有其他方法可以调用重载运算符),但是定义看起来很奇怪,代码如`lhs-> foo = rhs.foo;`.(有些编码标准也需要一个`if(!lhs){handle error}`块.)丑陋的四周.就个人而言,我喜欢refs,因为他们与其他开发者沟通,我没有重新安置. (2认同)

小智 6

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


Bil*_*ill 3

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

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

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

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.
Run Code Online (Sandbox Code Playgroud)

编辑:

由于 list1 是一个指针,我如何访问引用...?

你有两个选择。您可以取消引用指针以获取它指向的列表:

std::list<int>* list1 = user_defined_func();
std::list<int>& list1ref = *list1;
BOOST_CHECK_PREDICATE( validate_list, list1ref );
delete list1;
Run Code Online (Sandbox Code Playgroud)

当然,这可以缩短为:

std::list<int>* list1 = user_defined_func();
BOOST_CHECK_PREDICATE( validate_list, *list1 );
delete list1;
Run Code Online (Sandbox Code Playgroud)

您的验证函数可以采用指针而不是引用(记住将 L1.{something} 更改为 L1->{something}):

bool validate_list(std::list<int>* L1) { ... }
Run Code Online (Sandbox Code Playgroud)