#include <iostream>
using namespace std;
class MyClass {
int x;
public:
MyClass (int val) : x(val) {
cout << "constructed :" << this << endl;
}
int& get() {
cout << "x is : " << x << endl ;
return x;
}
};
int main () {
MyClass foo = {10};
foo.get() = 20;
foo.get();
foo = 30;
cout << &foo << endl;
foo.get();
}
我得到以下输出:
constructed :0x7fffc44ef920
x is : 10
x is : 20
constructed :0x7fffc44ef924
0x7fffc44ef920
x is : 30
为什么foo.get() = 20
这是改变&#39; x&#39;的价值的合法途径?在对象foo中?
另外,为什么foo = 30
在地址0x7fffc44ef924
处构建新对象?这个对象类型是什么?
为什么会这样:cout << &foo << endl;
打印在main函数开头实例化的原始MyClass foo对象的地址(地址0x7fffc44ef920
)?
你如何引用新的&#39; foo在地址0x7fffc44ef924
?
答案 0 :(得分:1)
为什么这个foo.get()= 20是改变&#39; x&#39;的价值的合法方式。在对象foo中?
因为您将引用返回到x以及引用的行为方式。事实上,我知道从函数(int &get()
)返回引用的唯一原因是允许这种行为。例如,如果您正在实现operator []。
有时你想要返回一个const引用(const int &foo()
)以避免复制值,但你只能用类或结构来做。
为什么这个foo = 30在地址上构造一个新对象 0x7fffc44ef924?这个对象类型是什么?
因为MyClass有一个带有一个int
参数的构造函数,所以编译器会将此解释为将int转换为MyClass的方法,这就是这里发生的事情。它等同于foo = MyCLass(int)
如果您不想要这种行为,可以将MyClass(int)声明为显式:
explicit MyClass( int val ) {...
为什么这个foo = 30在地址上构造一个新对象 0x7fffc44ef924?这个对象类型是什么?
为什么会这样:cout&lt;&lt; &amp; foo&lt;&lt; ENDL;打印的地址 原始的MyClass foo对象在main的开头实例化 功能(地址0x7fffc44ef920)?
首先,我上面描述的隐式MyClass(30)用于构造一个新的MyClass对象。该对象的地址恰好具有地址0x7fffc44ef924,然后将新对象复制到旧对象中,位于0x7fffc44ef920。可能如果你打开了优化,你只会看到一个地址,因为编译器会看到创建一个全新的对象然后复制它是一个CPU循环的浪费。
你如何引用新的&#39; foo在地址0x7fffc44ef924?
您无法在一行代码中创建和销毁该对象。一旦将其复制到原始对象上,如上所述,它就被删除了。
答案 1 :(得分:0)
通过在构造函数之前添加explicit
关键字,将构造函数更改为显式构造函数,如下所示:
explicit MyClass (int val) : x(val) {
cout << "constructed :" << this << endl;
}
然后,您将从编译器获得非常有用的消息:
prog.cc: In function 'int main()':
prog.cc:18:22: error: converting to 'MyClass' from initializer list would use explicit constructor 'MyClass::MyClass(int)'
MyClass foo = {10};
^
prog.cc:21:11: error: no match for 'operator=' (operand types are 'MyClass' and 'int')
foo = 30;
^~
prog.cc:5:7: note: candidate: 'constexpr MyClass& MyClass::operator=(const MyClass&)'
class MyClass {
^~~~~~~
prog.cc:5:7: note: no known conversion for argument 1 from 'int' to 'const MyClass&'
prog.cc:5:7: note: candidate: 'constexpr MyClass& MyClass::operator=(MyClass&&)'
prog.cc:5:7: note: no known conversion for argument 1 from 'int' to 'MyClass&&'
阅读并理解它。如果它们没有意义,那么你真的需要更多地学习C ++,例如一个book。