C++;参考及;C/C+中的常量指针+; 最近我在解释指针和引用(在C++编程的上下文中)对某人的基本区别时,我讲了通常的解释,这些函数讨论不同的函数参数传递约定——按值调用、指针调用、引用调用以及所有相关的引用理论。
但后来我想,无论C+引用在参数传递方面做了什么,(允许以一种内存高效的方式传递大型结构/对象,同时通过不允许被调用方修改作为引用传递的对象的任何变量(如果我们的设计需要的话)来保持安全) C中的const指针也可以实现同样的功能,例如,如果需要通过将结构指针强制转换为常量来传递结构指针,比如struct mystr*ptr-C++;参考及;C/C+中的常量指针+; 最近我在解释指针和引用(在C++编程的上下文中)对某人的基本区别时,我讲了通常的解释,这些函数讨论不同的函数参数传递约定——按值调用、指针调用、引用调用以及所有相关的引用理论。,c++,c,pointers,reference,C++,C,Pointers,Reference,但后来我想,无论C+引用在参数传递方面做了什么,(允许以一种内存高效的方式传递大型结构/对象,同时通过不允许被调用方修改作为引用传递的对象的任何变量(如果我们的设计需要的话)来保持安全) C中的const指针也可以实现同样的功能,例如,如果需要通过将结构指针强制转换为常量来传递结构指针,比如struct mystr*ptr- func(int,int,(const struct mystr*)(ptr)); ptr不是某种等同于参考的东西吗 如果不复制结构(通过指针传递),它将不会以内存效率高
func(int,int,(const struct mystr*)(ptr));
ptr不是某种等同于参考的东西吗
-AD您可以将常量引用绑定到右值:
void foo(const std::string& s);
foo(std::string("hello"));
void bar(const std::string* s);
bar(&std::string("hello")); // error: & operator requires lvalue
但不可能传递右值的地址:
void foo(const std::string& s);
foo(std::string("hello"));
void bar(const std::string* s);
bar(&std::string("hello")); // error: & operator requires lvalue
语言中引入了引用以支持运算符重载。您希望能够说a-b
,而不是&a-&b
。(请注意,后者已经有了一个含义:指针减法。)
引用主要支持按引用传递,指针主要支持引用语义。是的,我知道,C++中的区别并不总是很清楚。< P>有两种典型的用例场景: 第一:指针表示可选参数。由于引用不能是
NULL
,但指针可以以编码样式记录任何标记为指针的参数可能是NULL
,因此函数需要处理该问题。可选参数可以是常量或非常量,强制(引用)参数也可以是常量或非常量
第二:引用仅与const关键字结合使用,因为调用语法向读者建议传递值语义,这是按定义的常量。那么指针只用于被调用方可以更改的参数
我个人更喜欢第一种选择,因为在这四种情况下,“常量引用”、“非常量引用”、“常量指针”、“非常量指针”都有不同的含义。选项二仅区分两个“事物”:“函数可以修改该值”与“函数不会修改该值”。就引用对象而言,给定常量引用时,代码可以操作的内容与使用指向常量对象的指针时相同,类似地,给定一个非常量引用,它可以操作的操作与给定一个指向非常量对象的指针相同 引用阻止被调用函数执行的操作是更改引用引用的对象或引用上的指针算法 就调用者而言,const引用可以直接绑定到rvalue,并且在创建和销毁作为参数传递的对象时,您具有定义良好的语义。这是一个常见的习惯用法-为参数构造临时变量:
// declaration
void bar ( const Foo& );
// use
bar ( Foo() );
但是,这些中的Foo对象是否有超过函数调用长度的生命周期还不是很明显:
// declaration
void bar ( const Foo* );
// use
Foo temp;
bar ( &temp );
// cast to avoid warning about taking address of temporary
bar ( &static_cast<const Foo&>( Foo() ) );
// helper function to same effect
template<typename T> const T* address_of ( const T& t) { return &t; }
bar ( address_of ( Foo() ) );
//声明
空栏(常富*);
//使用
Foo-temp;
巴(和温度);
//强制转换以避免关于获取临时地址的警告
条形图(&static_cast(Foo()));
//辅助函数的作用相同
模板常数T*地址_of(常数T&T){return&T;}
(Foo()的地址);
虽然很明显,后者只是一个函数调用,应该使它显然是这样做的
基本上,引用是指向单个对象的指针的语法糖,而不是数组的开头。@难以捉摸:指针怎么会比引用更不“类型安全”呢?明白你的意思,但大多数情况下会将引用传递给一个对象/变量,它本质上是一个变量而不是常量,所以在这种情况下…@gold:Ah,你说的是非常量引用。是的,在这种情况下,我所看到的唯一实际区别(除了符号方便之外)是不存在
null
引用这一事实。因此,如果null
是一个有效选项,请使用指针,否则请使用引用。我不同意“使用指针的函数始终必须检查null”——如果有人向您传递null指针,通常是严重编程错误的结果,崩溃是最合理的。如果你有真正可选的参数,这表明你应该有一个不同的、重载的函数,或者你应该提取一个方法对象。@Billy ONeal:在这个模型中(这不是我一下子发明的)函数编写器需要确保只将那些参数表示为指针,如果将NULL
赋值实际上不是严重的编程错误。愚蠢的例子:如果您想要日志记录,请为函数提供一个非空的记录器。不那么愚蠢的(但C库)示例:。如果给NULL
赋值是错误的,函数应该首先引用。是的,这意味着大多数函数只接受引用(或者根据值,如果合适的话)。我想你把“常量指针”和“指向常量的指针”混淆了。太好了!但这个问题实际上可能是指它所说的:“常量指针”(就像一个引用,它不能反弹)而不是“指向常量的指针”。@Ben:我在OP中的意思是“常量obj1”,即指向常量obj的指针