我正在阅读v.sort_by(|x, y| key(x).cmp(&key(y)));
第4版:Stroustrup's
。我有一个The C++ Programming Language
背景,所以到目前为止前4章都很好。
在python/java
我看到了:
Chapter 3
这开始了一天的尝试来写这个问题:
首先我发现它正在返回对象的引用,而不是副本。正如我在此question中确认的那样。
我能够理解将引用返回complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; }
与此question
我做了自己的试验
reference variable
这让我质疑为什么叫class Test {
public:
Test():x{5}{}
int x;
void setX(int a) {x = a;}
Test& operator+=(Test z) {x+=z.x; return *this;}
// the keyword this is a pointer
Test* getTest() {return this;}
// but I can return the reference by *this
Test& getTest1() {return *this;}
// or I can return a copy
Test getTest2() {return *this;}
};
,所以我做了这个试验
de-reference
按预期int x = 8;
int* p = &x;
int y = *p;
int& z = *p;
x++; // let's have some fun
std::cout << y << std::endl;
std::cout << z << std::endl;
和y = 8
,z = 9
如何在一个案例中返回de-reference
,在另一个案例中返回address
?更重要的是value
如何做出这种区分?
答案 0 :(得分:3)
它与Test类函数完全相同。
int y = *p;
int& z = *p;
y
是p
指向的副本。
z
是对p
指向的(不是地址)的引用。因此,更改z
更改*p
,反之亦然。但更改y
对*p
没有影响。
答案 1 :(得分:1)
可以将指针int* p
视为指向类型为int
的数据所在的地址。当您取消引用它时,系统将检索该内存地址的值(该地址是p
本身的实际值)。在int y = *p;
的情况下,您将int
值的副本放在堆栈上locator value y
。
另一方面,在*p = 13;
左侧取消引用意味着您要替换存储在由{的值表示的内存地址处的int
值*p
{1}}使用右侧值p
。
13
中的参考左值int& z
不 int& z = *p;
所指向的int
值的副本,而非左手对p
返回的特定内存地址处的任何内容的引用(即*p
自身保存的实际值)。
这并不意味着你的设计案例会有很大的不同,例如给定p
类,Foo
值,
Foo::incrementCount()
同一实例的相同方法将被调用两次。相反,Foo* p = new Foo();
p->incrementCount();
Foo& ref = *p;
ref.incrementCount();
实际上将复制整个Foo foo = *p
实例,在堆栈上创建单独的副本。因此,调用Foo
不会影响foo.incrementValue()
仍指向的单独对象。
答案 2 :(得分:1)
正如预期的那样y = 8且z = 9,那么在一种情况下,取消引用如何返回地址,而另一种情况下的值是如何返回的?更重要的是,C ++如何做出这种区分?
取消引用返回了两种情况下引用的实际内容。所以C ++没有区别。不同之处在于取消引用的结果。
如果您执行int j = <something>;
,则会使用某些内容的结果来初始化j
。由于j
是整数,<something>
必须是整数值。
如果你int &j = <something>;
,那么某些内容的结果仍会用于初始化j
。但是现在,j
是对整数的引用,<something>
必须是整数,而不仅仅是整数值。
那么,*this
在两种情况下的作用是相同的。如何使用值并不会影响该值的计算方式。但是如何使用它会影响使用它时会发生什么。这两段代码使用不同的解引用对象。在一种情况下,取其值。在另一种情况下,引用绑定到它。