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

I am a bit lost in C ++ operators. I would like to trigger an assignment operator for two different classes, i.e. They can be assigned 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 job seems to do the job, called "B". Likewise, for "c = b", "C" is called. However, when I uncomment the second part, I get a linker error. If I define operator A, for example:

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

      

I get "B", "A". AND? Can anyone explain why "A" is needed when two Bs are assigned, but not when B <C is?

+3


source to share


3 answers


The compiler generates an implicit copy assignment operator that is selected when you do the B = B assignment. It is not selected when you do the 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 there is a linker error internally B::operator=(B const&)

, which since you haven't defined it means it should be automatically generated.

+2


source


When you assign b = b2;

, it tries to do the default (implicit) assignment B. And the default assignment will call the default assignment of the base class, so it will eventually call A::operator=(const A &a)

, which is pure virtual.



And you will get a communication error.

+2


source


According to the standard overriding base class virtual assignment operator, the derived class does not prevent the generation of the default assignment operator that is called in your case. This default copy assignment operator of the class B

will directly call the class copy assignment operator A

, which is why you get the error undefined reference

.

13.5.3 Assignment [over.ass]

2 Any assignment operator, even copy and move assignment operators, can be virtual. [Note. For a derived class D with a base class B for which a virtual copy / move assignment is declared, the copy / move assignment operator in D does not override the virtual copy / move assignment operator of the virtual machine Bs. [Example:

struct B {
    virtual int operator= (int);
    virtual B& operator= (const B&);
};

struct D : B {
    virtual int operator= (int);
    virtual D& operator= (const B&);
};

D dobj1;
D dobj2;
B* bptr = &dobj1;

void f()
{
    bptr->operator=(99); // calls D::operator=(int)
    *bptr = 99; // ditto
    bptr->operator=(dobj2); // calls D::operator=(const B&)
    *bptr = dobj2; // ditto
    dobj1 = dobj2; // calls implicitly-declared D::operator=(const D&)
}

      

+1


source







All Articles