C ++:隐式成员函数

时间:2014-02-27 06:56:08

标签: c++

请考虑我编写的以下代码:

#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

为什么会这样?

2 个答案:

答案 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);

aSample时,a = b;a.operator= (b);相同。这仅在bSample&时才有效。 getK的返回值是临时Sample,不允许对临时值的非常量左值引用(换句话说,Sample&变量)请参见this question

如果让getK返回对样本(Sample&)的左值引用,那么将它传递给赋值运算符是没有问题的。或者,如果你的赋值运算符采用了一个const左值引用(const Sample&),那么将它绑定到临时对象就没有问题了。