这是OOP高级课程考试中的一个问题,用C ++教授(TAU大学,本学期):
问:C ++指针和引用有什么区别?
A. A reference is the entire object while a pointer is only the address of it. B. The same meaning, and difference is only in syntax and usage. C. The syntax used to access the object. D. Pointers are simple address to the object while a reference uses the virtual table.
哪个是正确答案?
课程老师声称A是正确的,并且对象的引用实际上是对象本身。那是对的吗?我意识到访问引用等同于访问对象本身,但是,在破坏引用时,我们不会破坏对象本身。引用是对象的替代名称,但是说reference == object true?
BTW,讲师给了the following link to an faq as support for his claim,引用了一句话:“重要提示:即使是 参考通常使用 底层程序集中的地址 语言,请不要想到 引用作为一个有趣的指针 到一个对象。 参考是 对象 即可。它不是指针 对象,也不是对象的副本。它 是对象。“
但是,我认为这是不正确的。
答案 0 :(得分:37)
他们都错了。
引用本质上是另一个对象的同义词。在内部,它通常被实现为指针,但它的语法就像它所引用的对象一样。
指针是一个单独的对象,它存储它指向的对象的内存地址(如果它没有指向对象,则为0)。
你可以说引用是它引用的对象(它当然就是那样),但事实并非如此。如果引用超出范围,则引用的对象不会被破坏,因此引用不是对象。
答案 1 :(得分:7)
引用和对象之间存在区别 - 您可以对同一对象进行多次引用。对象具有“身份”,而引用本身并不是真的。
虽然引用的机制与指针的机制完全不同,但我从概念上说,引用实际上与指针非常相似。
答案 2 :(得分:5)
(B)是最接近的,但仍然不完全正确。引用是const指针的语法糖。就像一个const指针一样,它必须在初始化时绑定到左值,并且永远不会被反弹。就像一个const指针,它是多态的。
编辑:(A)不正确的简短证明,因为至少有几个人在为它辩护:
struct A { int x; int f() { return 1; } }
struct B : public A { int y; int f() { return 2; } }
B b;
A& a = b;
assert(sizeof(a) == sizeof(b)); // fail
assert(a.f() == b.f()); // fail again
答案 3 :(得分:4)
只是为了爬上我的爱好马,大学没有教导人们如何用特定的计算机语言编程。他们这样做的事实仅仅是他们在过去30年中变得多么退化的一个指标。我从1979年到1983年在伦敦大学工作,担任微生物学技术员和程序员,微生物学学生(请注意不是CS学生!)应该学会如何使用计算机并自己或多或少地编程,他们做了,尽可能多。
但是现在即使是CS学生也似乎已经把所有东西都舀了下来,并且通过几乎不可能通过OP引用的测试来测试那些“知识”。
尔加!!!
答案 4 :(得分:3)
重要的是区分:
常见问题解答和老师似乎都在谈论第一点,但老师的问题就像是在询问第二点一样。为了解释FAQ的观点,请考虑标准描述的表达处理的第一阶段
如果表达式最初具有“对T的引用”类型(8.3.2,8.5.3),则在进行任何进一步分析之前将类型调整为“T”,表达式指定由引用表示的对象或函数,表达式是左值
在转换之后,使用该表达式无法再区分引用及其指定的对象或函数。但这并没有使对象等同于对象。前者只是将引用到后者。更不用说,因为引用也可以引用函数。
现在,引用本身只是 - 一个碰巧引用对象或函数但实际上不存储某些东西的实体。
当人们说C中的数组只是指针时,人们有时会提出争论中的同样错误。它们的真正含义是表达式中的数组(大多数)只是指针。但这并不能使两者本身相等。
答案 5 :(得分:1)
所有答案都不正确,A最接近。
指针是对象本身的对象地址
“对象”是记忆中某处的“某物”。类实例,int,float等。
Reference是一种访问对象的替代方法。它是对象的引用,而不是对象本身。它可能会也可能不会被实现为指针。您可以将其视为替代对象名称,但这不完全正确。我能想到的最接近的正确描述是“访问/操纵对象的替代界面”(不幸的是,如果你考虑OOP,“界面”听起来会产生误导,尽管它是(IMO)最正确的)。
答案 6 :(得分:1)
回答老师是否错了: 简单的逻辑。严格地说,它是名称(和标准)所说的:对象的引用(=“名称”),对象本身 NOT 。如前所述,当引用变量超出范围时,不会调用对象的析构函数,因此引用不对象。
#include <iostream>
class A {
public:
~A()
{
std::cout << "~A() called.\n";
}
};
void f(A &a)
{
// a running out of scope...
}
int main()
{
A a;
std::cout << "calling f()\n";
f(a);
std::cout << "done calling f()\n";
return 0;
}
答案 7 :(得分:1)
我没有提到的指针和引用之间的一个重大区别是指针可以是NULL而引用不能。这并不意味着引用指针的对象不能超出范围,导致人们对指针的问题类型相同,只是没有“未分配”状态。
答案 8 :(得分:0)
我相信你的老师混淆了一个隐喻和一个具体的陈述。一个引用肯定是不实际对象,它是实现为“有趣的指针”,但该语句的要点是你要将引用视为在引用的实际对象中,您不应该像处理指针一样思考或编程。从语法上讲,访问对象的引用与访问对象本身是相同的,除了在下面的注释中提到的一些情况。
答案 9 :(得分:0)
让我们一次评估一个选项 -
甲。引用是整个对象,而指针只是它的地址。
没有“整个对象”这样的东西!它只是对象。许多引用可以指向对象,然后即使对象本身继续存在,也不再引用它。 错误的答案!
B中。相同的含义,区别仅在于语法和用法。 这是 NOT 相同的事情。例如,当你得到&amp; ref - 你不能做ref ++,就像你得到* ptr一样,你可以做ptr ++。 指针不仅允许您访问对象,还允许指针算术;因此,使用指针,您不仅可以传递1个地址(并修改该地址),而且可以使用相同的语法传递任意位置的整个数组。你不能参考这个! 错误的答案!
℃。用于访问对象的语法。 没有完全理解它如何构成两个概念之间的区别。 错误的答案!
d。指针是对象的简单地址,而引用使用虚拟表。 我没有东西有什么称为虚拟表。指针通常指向堆,其中引用是位于堆栈内的指针。 错误的答案!
一切都错了......
DIPAN。
答案 10 :(得分:-1)
问题不是关于对象和引用,而是关于指针和引用。关键是指针表示内存位置,引用表示对象 - 更高级别的语义结构。就那么简单。
老师已经给你答案了:A - &gt;正确答案。
祝你学习顺利。