1
15
我猜你错过了C++和C++语义的要点。你错过了事实 C++在传递(几乎)所有的值时是正确的,因为它总是在C中完成。 . 但不仅仅是在C中,我将在下面向您展示… C上的参数语义在C语言中,所有内容都是按值传递的。”原语“和”pods“通过复制它们的值来传递。在函数中修改它们,原始的将不会被修改。不过,复制一些pods的成本可能是不平凡的。 使用指针表示法(the*)时,不会通过引用传递。您正在传递地址的副本。这或多或少是相同的,但有一个细微的区别:
p->值的最终值为32。因为P是通过复制地址的值来传递的。原来的P没有修改(新的P泄漏了)。 Java和C Sharp的参数语义对一些人来说可能是令人惊讶的,但是在Java中,所有的东西都是用价值复制的。上面的C示例将在Java中给出完全相同的结果。这几乎是您想要的,但是您不能像在C中那样轻松地“通过引用/指针”传递原语。 在C中,他们添加了“ref”关键字。它或多或少类似于C++中的引用。关键是,在C上,您必须在函数声明和每个调用上都提到它。我想这又不是你想要的。 C++中的参数语义在C++中,几乎所有东西都是通过复制值传递的。当你只使用符号的类型时,你就是在复制符号(就像在C语言中一样)。这就是为什么在使用*时,要传递符号地址的副本。 但是,当您使用&时,假设您正在传递实际对象(无论是结构、int、指针还是其他对象):引用。 很容易把它误认为语法糖(即,在幕后,它就像一个指针,生成的代码与指针使用的代码相同)。但是… 事实上,这个参考不仅仅是合成糖。
所以,参考文献是两全其美的。 让我们看看C示例,但是在DoMothTurnFor函数上有C++的变化:
结果是42,旧的P被泄漏了,被新的P替换了。因为,与C代码不同,我们不会传递指针的副本,而是传递对指针的引用,即指针本身。 当使用C++时,上面的例子必须是清晰的。如果不是,那你就错过了什么。 结论C++是通过拷贝/值传递的,因为它是一切工作的方式,无论是在C、C还是Java(甚至在JavaScript……)-…P)。和C++一样,C++有一个引用操作符/关键字, 作为奖金 . 现在,据我所知,你也许在做我称之为半开玩笑的事。 C+ 也就是说,C具有一些有限的C++特性。 也许你的解决方案是使用Type Debug(它会激怒你的C++同事,但是看到代码被无用的Type……污染),但是这样做只会混淆你在那里真正丢失C++的事实。 正如在另一篇文章中所说的,你应该改变你的思维方式,从C开发(无论什么)到C++开发,或者你应该移动到另一种语言。但是不要用C++特性来编程C方式,因为有意识地忽略/混淆你使用的成语的力量,你会产生次优的代码。 注意:除了原语之外,不要通过复制传递任何内容。你会从你的OO能力去掉你的功能,在C++中,这不是你想要的。 编辑问题是 有点 修改(见) https://stackoverflow.com/revisions/146271/list )我让我的原始答案,并回答下面的新问题。 在C++上,你如何看待默认通过引用语义? 如您所说,它将破坏兼容性,并且对于原语(即内置类型,仍将通过复制传递)和结构/对象(将作为引用传递)具有不同的传递方式。您必须添加另一个运算符来表示“传递值”(外部的“c”非常糟糕,已经用于其他非常不同的内容)。不,我真的很喜欢今天C++中的方式。 […]引用运算符在我看来是获取变量地址的一种方法,这是我用于获取指针的方法。我的意思是,它是同一个操作符,但是在不同的上下文中有不同的语义,这对你来说不是也有点错吗? 当和C++流一起使用时,操作符和gt;& gt;改变了它的语义。然后,可以使用operator+=替换strcat。我想,之所以使用运算符是因为它的含义是“指针的对立面”,而且因为它们还不想使用另一个符号(ASCII是有限的,作用域运算符::以及指针->表示其他符号很少可用)。但是现在,如果你感到困扰,那么& & & &将真的让你神经紧张,因为他们在C++0X(一种超级引用……)中添加了一元和(一)。我还没自己消化… |
2
10
对我来说,完全改变一段代码含义的编译器选项听起来是一个非常糟糕的主意。要么使用C++语法,要么找到不同的语言。 |
3
2
我不想再通过使每个(非限定)参数都成为引用来滥用引用了。 添加到C++中的主要原因是 to support operator overloading ;如果您想要“通过引用”语义,C有一个非常合理的方法来实现它:指针。 使用指针可以清楚地表明您更改被指向对象的值的意图,并且只通过查看函数调用就可以看到这一点,您不必查看函数声明来查看它是否在使用引用。 此外,参见
|
4
1
是的,我认为这是一个相当混乱的超载。 这就是微软对这种情况的看法:
我在C或C++上不是很好,但是我得到了更大的头痛,整理了两种语言中的*和ANP的不同用法,而不是汇编程序中的编码。 |
5
1
最好的建议是养成思考自己真正想要发生什么的习惯。当您没有复制构造函数(或者不想使用它)并且大型对象更便宜时,通过引用传递是很好的。然而,参数的突变是在类外感觉到的。你可以顺便过去
每一个排列(按值/参照和常量/非常量)都有重要的差异,这些差异肯定是不等价的。 |
6
1
当通过值传递时,您正在将数据复制到堆栈。如果为要传递的结构或类定义了operator=我所知道的编译器指令中没有一个会冲走隐含语言混淆的老生常谈,而这种语言混淆是被提议的更改所固有的。 一个常见的最佳实践是通过常量引用传递值,而不仅仅是通过引用传递值。这样可以确保调用函数中的值不能更改。这是const-correct代码基的一个元素。 完全正确的代码库更进一步,在原型的末尾添加了常量。考虑:
如果要将一个foo对象传入一个以const为前缀的函数,则可以调用printstats()。编译器在调用changeStats()时出错。
|
7
1
老实说,C++中的整个值传递/引用概念是误导性的。 一切 是传递值。您有三个案例:
我个人认为,记住一切都是有价值的。在某些情况下,该值可能是一个地址,它允许您更改函数之外的内容。 你的建议不允许程序员做1。我个人认为取消这个选择是个坏主意。C/C++的一个主要优点是有细粒度的内存管理。让一切通过引用仅仅是试图使C++更像Java。 |
8
0
有些事情不清楚。当你说:
你打算用第二个“B”做什么?你忘了介绍一种类型吗?你忘了写首字母“b”的不同吗?你不觉得写这样的东西很清楚吗?
从现在起,我想你是指我写的东西。 现在,您的问题是:“您不认为编译器会将非pod的每个pass-by值视为pass-by-ref会更好吗?”. 第一个问题是它会破坏你的合同。我想你的意思是通过常量引用,而不仅仅是引用。 现在您的问题简化为:“您知道是否有一些编译器指令可以按值优化函数调用吗?” 现在的答案是“我不知道”。 |
9
0
我认为,如果你开始混合所有可用的参数,以及它们的常量变化,C++会变得非常混乱。 它很快就失去了控制,无法跟踪所有复制构造函数调用,所有取消引用都过载了,等等。 |