Search code examples
c++operator-overloadingassignment-operator

Why can't have I a pure virtual assignment operator?


I'm a bit lost in C++ operators. I'd like to enforce the assignment operator for two different classes, i.e. so one can assign one to each other:

class A {
public:
    virtual A &operator =(const A &a) = 0;
};

class B : public A {
public:
    virtual A &operator =(const A &a) override {
        std::cout << "B" << std::endl;
        return *this;
    }
};

class C : public A {
public:
    virtual A &operator =(const A &a) override {
        std::cout << "C" << std::endl;
        return *this;
    }
};

int main(int argc, char *argv[])
{
    B b;
    C c;
    b = c;

    // leads to a linker error: undefined reference to `A::operator=(A const&)'
    //B b2;
    //b = b2;
}

The first assignment seems to do the job, "B" is called. Similarly, for "c = b", "C" is called. However when I uncomment the second part, I get the linker error. If I define A's operator like:

virtual A &operator =(const A &a) {
        std::cout << "A" << std::endl;
        return *this;
} 

I get "B", "A". Huh? Can somebody explain why "A" is needed when two B's are assigned but not when B <- C is?


Solution

  • The compiler generates an implicit copy-assignment operator that is being selected when you do a B = B assignment. That is not selected when you do a B = C assignment.

    http://en.cppreference.com/w/cpp/language/copy_assignment

    https://wandbox.org/permlink/CM5tQU656rnwtrKl

    If you look at your error message:

    /tmp/cctHhd0D.o: In function `B::operator=(B const&)':
    prog.cc:(.text._ZN1BaSERKS_[_ZN1BaSERKS_]+0x1f): undefined reference to `A::operator=(A const&)'
    collect2: error: ld returned 1 exit status
    

    You can see that the linker error is from inside B::operator=(B const&), which, since you didn't define one, means it must be auto-generated.