请考虑我编写的以下代码:
#include <iostream>
using namespace std;
class Sample{
int a;
public:
Sample(){a=0;cout << "Sample Created (Default Constructor)" << endl;}
Sample(int n):a(n){cout << "Sample Created" << endl;}
~Sample(){ cout << "Sample destroyed" << endl;}
Sample(Sample& s){a=s.getA(); cout << "Sample Copy Constructor called" << endl;}
Sample& operator= (Sample& s){this->a=s.getA(); cout << "Assignment Operator Called" << endl;return (*this);}
void setA(int n){ a=n;}
int getA(){return a;}
};
class Test{
Sample k;
public:
Test(){ cout << "Test Created(Default Constructor)" << endl;}
Test(Sample& S):k(S){ cout << "Test Created" << endl;}
~Test(){cout << "Test Destroyed" << endl;}
Test& operator= (Test& test){ k = test.getK(); cout << "Test Assignement Operator called" << endl; return (*this); } // Here 1
Test(Test& test){k=test.getK();cout << "Test Copy Constructor called" << endl;}
Sample getK(){return k;} // Here 2
void setK(Sample& s){k=s;}
};
int main()
{
Sample a1(5);
//Sample a2,a4;
//a2=a1=a4;
//Sample a3(a2);
Test b1(a1);
Test b2=b1;
//b2=b1;
return 0;
}
我在编译时遇到错误:
$ g++ -Wall Interview.cpp -o Interview
Interview.cpp: In member function `Test& Test::operator=(Test&)':
Interview.cpp:23: error: no match for 'operator=' in '((Test*)this)->Test::k = Test::getK()()'
Interview.cpp:12: note: candidates are: Sample& Sample::operator=(Sample&)
Interview.cpp: In copy constructor `Test::Test(Test&)':
Interview.cpp:24: error: no match for 'operator=' in '((Test*)this)->Test::k = Test::getK()()'
Interview.cpp:12: note: candidates are: Sample& Sample::operator=(Sample&)
当我对here 2
进行更改为 - Sample& getK(){return k;}
时,它会完美编译。
有人可以解释原因吗?
如果函数定义为here 1
Test& operator= (const Test& test){ k = test.getK(); cout << "Test Assignement Operator called" << endl; return (*this); }
我收到错误 -
$ g++ -Wall Interview.cpp -o Interview
Interview.cpp: In member function `Test& Test::operator=(const Test&)':
Interview.cpp:23: error: passing `const Test' as `this' argument of `Sample& Test::getK()' discards qualifiers
为什么会这样?
答案 0 :(得分:3)
首先,复制构造函数和赋值运算符采用非const左值引用。例如,
Test& operator= (Test& test)
这意味着临时数不能作为参数绑定到这些构造函数/运算符。由于这个原因,规范签名使用const
引用,因为改变操作数是没有意义的:
Test& operator= (const Test& test)
^^^^^
这将允许绑定临时工具:
Test foo () { return Test(); }
Test t0;
t0 = foo();
其次,您的“getters”必须为const
,以便可以在const
个实例上调用它们,或者通过const
指针或引用调用它们:
Sample getK() const {return k;}
^^^^^
答案 1 :(得分:1)
您已定义了这些运算符:
Sample& Sample::operator= (Sample& s);
Test& Test::operator= (Test& test);
当a
为Sample
时,a = b;
与a.operator= (b);
相同。这仅在b
为Sample&
时才有效。 getK
的返回值是临时Sample
,不允许对临时值的非常量左值引用(换句话说,Sample&
变量)请参见this question。
如果让getK
返回对样本(Sample&
)的左值引用,那么将它传递给赋值运算符是没有问题的。或者,如果你的赋值运算符采用了一个const左值引用(const Sample&
),那么将它绑定到临时对象就没有问题了。