2010-02-24 43 views
5

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

#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)); 

,我被告知,我无法通过指针功能期待参考。我认为一个指针(没有被去引用)只是一个地址(即一个引用)。我在这里错过了什么?

回答

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. 

编辑:

,因为列表1是一个指针,我怎么访问参考...?

你有两种选择。你可以反引用指针得到它指向列表:

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) { ... } 
+0

从user_defined_func()我得到一个指针,指向它创建的列表。 因此,这个指针返回到我的BOOST_AUTO_TEST_CASE中的list1指针变量 现在由于list1是一个指针,我如何访问list1指针指向的(object?)的引用? – leeand00 2010-02-24 16:18:08

+1

@ leeand00:好问题。我用我的答案编辑了我的帖子。 – Bill 2010-02-24 16:31:44

+0

好吧,我需要更改我的validate_list函数,以便它使用指针而不是引用。这清除了它。 自从我完成了C++之后已经有一段时间了,我没有记住或者不是一个引用和非引用指针之间存在差异的ware。 – leeand00 2010-02-24 17:21:19

6

你有错误的方式 - 引用可能使用指针来实现(尽管你通常不应该考虑这些),但C++中的指针不是引用。您可能会感到困惑,因为在C中,使用指针传递的东西被称为“通过引用调用”,但那是因为C没有像C++那样的真实引用。

+0

而downvote的原因是...... – 2010-02-24 14:38:47

+1

你dint'提供任何额外的解释。只是指出指针不是引用是不够的,OP已经看到了。他可能期待解释“如何”和“为什么”。 – 2010-02-24 14:41:28

+1

@Pop如果我们打算开始下调不能满足个人用户期望的答案,那么我们很少有人会留下任何代表。这是一个技术性的网站,并且应该为技术性错误预留downvotes。 – 2010-02-24 14:45:19

1

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

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

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

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

引用编译器处理指针,给出的对象不必解引用,但它仍然是指向同一对象的指针。

使你的代码工作,你需要做的

BOOST_CHECK_PREDICATE(validate_list, (*list1)); 

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

我觉得这个问题,答案是沿着相同的路线 What are the differences between a pointer variable and a reference variable in C++?

+0

@Charles这不能解决我在上面发布的代码。我已经尝试过了。 – leeand00 2010-02-24 16:10:41

+0

@Charles我正在使用Visual Studio 2005,这有什么关系呢? – leeand00 2010-02-24 16:18:54

+0

嗯,它是一个助推测试宏,也许有一个特殊的助推效用函数,您需要用来取消引用指针 – Charles 2010-02-24 16:38:22

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**),但引用不能引用其他引用(即,虽然请注意C++ 0x将使用T&&来定义移动语义,但不存在T&&之类的事情)。因此,您不能拥有引用数组。 (谢谢AshleysBrain)

有人可能会问我们为什么我们有所有引用,而不是所有的时间只使用指针(如在C中)。原因是运营商超载或某些运营商。

考虑赋值运算符。函数语法没有引用会是什么?如果是T* operator=(T* lhs, T rhs)那么我们不得不写的东西,如:

int a(1); 
&a = 2; 

从本质上讲,引用允许我们有左值的功能,而不需要指针引用和间接引用语法。

+2

实际上,'b = * a'完全合法,但它执行副本并且不会重置参考资料。至于'operator =(T * lhs,T rhs)',编译器可以为你隐藏'&a'(只有在操作符重载的情况下,因为没有其他方法可以调用重载操作符),但是定义看起来很奇怪,代码如'lhs-> foo = rhs.foo;'。 (有些编码标准也会要求'if(!lhs){handle error')块。)四处丑陋。就我个人而言,我喜欢参考,因为他们与其他开发者沟通,我没有重新安置。 – 2010-02-24 15:05:38

+0

+1迈克D,但没有投票支持这个答案,直到'b = * a'被正确描述! – 2010-02-24 15:14:49

+0

只是一个警告,'T&B = 0'是不可能的,'T&b = *((T *)0)';)另外,引用可能是悬空的!我仍然不明白为什么决定会有2个调用样式('.'和' - >'),而一个看起来非常好! – 2010-02-24 15:17:56

相关问题