免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4592 | 回复: 15
打印 上一主题 下一主题

请问引用到底是什么类型?(挺迷惑的) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-10 20:01 |只看该作者 |倒序浏览
对引用属于什么类型一直不清楚,以前看过某人的帖子说"引用不是一种数据类型,所以没有引用的引用,也没有指向引用的指针",不知是否正确?
可我觉得引用与指针本质没什么区别,引用应该也算一种数据类型。

int func1(int &;
int func2(int *);

传一个int型的实参,func1正确,而func2错误,提示是不能将int转换为int*,这个容易理解,func2需要
int*参数,但为什么第一个正确?难道引用的类型就是其引用对象的数据类型?还是因为int可以转化成int &?

同学给我的解释:int &ref=a;  int *ptr=&a;所以func1正确,而func2错误,好像有道理,但感觉没点中要害。
困惑中,没baidu出答案,请了解的dx们不吝指点。

论坛徽章:
0
2 [报告]
发表于 2007-04-10 20:10 |只看该作者
引用就是一种全新的东西,它有它自己的特征,使用场所。你的问题,就是试图用把引用等价到你已经学过的某一种东西,而并没有把引用当作是全新的东西来对待。
如果能用简单的&a或者*a之类的东西能解释引用,引用也就失去了它存在的价值。
换个思路,把引用当做是全新的东西去接受。

论坛徽章:
0
3 [报告]
发表于 2007-04-10 20:30 |只看该作者
by value 和 by reference 是对立统一的两个概念。记得 Visual Basic 里有 ByVal 和 ByRef 两个关键字,有兴趣的话可以到 MSDN 那里查一查。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2007-04-10 21:03 |只看该作者
引用的底层是利用了指针,为了取代C语言里传指针引起的不便(或许传指针有些看不清楚)。

论坛徽章:
0
5 [报告]
发表于 2007-04-10 21:05 |只看该作者
你可以看在编译原理中, 对于函数参数的介绍.

传引用. 值拷贝.

C语言实际只有值拷贝一个概念.
CPP的传引用可能是编译器解释的...具体查找方向估计应该是CPP标准等

论坛徽章:
0
6 [报告]
发表于 2007-04-10 21:18 |只看该作者
一个引用就是某对象的另一个名字。引用的主要用途是为了描述函数的参数和返回值,特别是为了运算符的重载。(TC++PL 5.5)


http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29
(From Wikipedia, the free encyclopedia)


In the C++ programming language, a reference is a simple reference datatype that is less powerful but safer than the pointer type inherited from C, which is a reference in the general sense but not in the sense used by C++.

Syntax and terminology
The declaration of the form

<Type> & <Name>...
where <Type> is a type and <Name> is an identifier is said to define an identifier whose type is reference to <Type>.

Examples:

int A = 5;
int A;
int& rA = A;
extern int& rB;
int& foo ();
void bar (int& rP);
class MyClass { int& m_b; /* ... */ };
int funcX() { return 42 ; }; int (&xFunc)() = funcX ;
Here, rA and rB are of type "reference to int", foo() is a function that returns a reference to int, bar() is a function with a reference parameter, which is reference to int, MyClass is a class with a member which is reference to int, funcX() is a function that returns an int, xFunc() is an alias for funcX.

Types which are of kind "reference to <Type>" are sometimes called reference types. Identifiers which are of reference type are called reference variables. To call them variable, however, is in fact is a misnomer, as we will see.


Relationship to pointers
C++ references differ from pointers in several essential ways:

It is not possible to refer to a reference object directly after it is defined; any occurrence of its name refers directly to the object it references.
As a consequence of the first point, neither arithmetic, casts, nor any other operation can be performed on references except copying their binding into other references.
Once a reference is created, it cannot be later made to reference another object; we say it cannot be reseated. This is often done with pointers.
References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.
References cannot be uninitialized. Because it is impossible to reinitialize a reference, they must be initialized as soon as they are created. In particular, local and global variables must be initialized where they are defined, and references which are data members of class instances must be initialized in the initializer list of the class's constructor.
e.g

int &k; // compiler will complain: error: `k' declared as reference but not initialized
There is a simple conversion between pointers and references: the address-of operator (&) will yield a pointer referring to the same object when applied to a reference, and a reference which is initialized from the dereference (*) of a pointer value will refer to the same object as that pointer, where this is possible without invoking undefined behavior. This equivalence is a reflection of the typical implementation, which effectively compiles references into pointers which are implicitly dereferenced at each use.

A consequence of this is that in many implementations, operating on a variable with automatic or static lifetime through a reference, although syntactically similar to accessing it directly, can involve hidden dereference operations that are costly.

Also, because the operations on references are so limited, they are much easier to reason than pointers and are more resistant to errors. While pointers can be made invalid through a variety of mechanisms, ranging from carrying a null value to out-of-bounds arithmetic to illegal casts to producing them from random integers, a reference only becomes invalid in two cases:

If it refers to an object with automatic allocation which goes out of scope,
If it refers to an object inside a block of dynamic memory which has been freed.
The first is easy to detect automatically due to static scoping of variables; the second is more difficult to assure, but it is the only concern with references, and one suitably addressed by a reasonable allocation policy.


Uses of references
Other than just a helpful replacement for pointers, one convenient application of references is in function parameter lists, where they allow passing of parameters used for output with no explicit address-taking by the caller. For example:
void square(int x, int& result) {
     result = x*x;
}
Then, the following call would place 9 in y:

square(3, y);
However, the following call would give a compiler error, since reference parameters not qualified with const can only be bound to addressable values:

square(3, 6);
Returning a reference also allows a surprising syntax in which function calls can be assigned to:
int& preinc(int& x) { ++x; return x; }
preinc(y) = 5;   // same as ++y, y = 5
In many implementations, normal parameter-passing mechanisms often imply an expensive copy operation for large parameters. References qualified with const are a useful way of passing large objects between functions that avoids this overhead:
void f_slow(BigObject x) { /* ... */ }  
void f_fast(const BigObject& x) { /* ... */ }
BigObject y;
f_slow(y); // slow, copies y to parameter x
f_fast(y); // fast, gives direct read-only access to y
If f_fast() actually requires its own copy of x that it can modify, it must create a copy explicitly. While the same technique could be applied using pointers, this would involve modifying every call site of the function to add cumbersome address-of (&) operators to the argument, and would be equally difficult to undo, if the object became smaller later on.


Quotes
References are defined by ISO/IEC 14882:1998(E), the ISO C++ standard, in section 8.3.2 [dcl.ref], as follows (excluding the example section):

In a declaration T D where D has the form
& D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of the identifier of D is “derived-declarator-type-list reference to T.” Cv-qualified references are ill-formed except when the cv-qualifiers (const and volatile) are introduced through the use of a typedef (7.1.3) or of a template type argument (14.3), in which case the cv-qualifiers are ignored. [Example: in
typedef int& A;
const A aref = 3; // ill-formed;
// non-const reference initialized with rvalue
the type of aref is “reference to int”, not “const reference to int”. ] [Note: a reference can be thought of as a name of an object. ] A declarator that specifies the type “reference to cv void” is ill-formed.
It is unspecified whether or not a reference requires storage (3.7).
There shall be no references to references, no arrays of references, and no pointers to references. The declaration of a reference shall contain an initializer (8.5.3) except when the declaration contains an explicit extern specifier (7.1.1), is a class member (9.2) declaration within a class declaration, or is the declaration of a parameter or a return type (8.3.5); see 3.1. A reference shall be initialized to refer to a valid object or function. [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bitfield. ]

论坛徽章:
0
7 [报告]
发表于 2007-04-10 21:32 |只看该作者
引用某种意义上来说就是常量指针
int num;
int &ref_num = num; //  int * const ptr_num = &num;
其中ref_num和ptr_num可以认为相同, 但是也不必非要理解的很清楚.引用主要用在函数参数传递中. 其他地方几乎不使用引用. 引用还指针虽然非常相似,但是他们还是有着细微的区别的.

论坛徽章:
0
8 [报告]
发表于 2007-04-10 21:42 |只看该作者
引用就是指针。但是引用的语法和指针不一样。

最明显一点是,指针可以指向内存地址0,或者是野指针;而引用不会这样(why ? hehe)。

论坛徽章:
0
9 [报告]
发表于 2007-04-10 21:58 |只看该作者
原帖由 yuanchengjun 于 2007-4-10 21:42 发表
引用就是指针。但是引用的语法和指针不一样。

首先一点,引用不是指针,我只是说在某种意义上.希望你能明白

论坛徽章:
0
10 [报告]
发表于 2007-04-10 22:00 |只看该作者
引用只是它引用的变量的一个别名而已,应该说是一个符号
int &a=b; 你可以输出一下a和b的内存地址,结果是一样的,都是b的地址。如:
std::cout << &a <<std::endl;
std::cout << &b <<std::endl;

指针本身是一个变量,它有自己的内存地址,而它的地址存贮的内容是它指向的变量的地址。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP