代码之家  ›  专栏  ›  技术社区  ›  Ayrosa

在[over.ass]/2中的示例中,为什么*bptr=dobj2;调用D::运算符=(常量B&)?

  •  1
  • Ayrosa  · 技术社区  · 6 年前

    [over.ass]/2

    我能理解为什么 bptr->operator=(dobj2); 电话 D& operator= (const B&) 为什么 dobj1 = dobj2; 调用隐式声明的 D::operator=(const D&) . 但我不太确定 *bptr = dobj2; .

    例子:

    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&)
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   gchen    6 年前

    当您有一个指向派生实例的基指针或引用并对其调用虚拟成员函数时,就会发生多态性。

    在您的示例中

    bptr->operator=(99); // calls D::operator=(int)
    bptr->operator=(dobj2); // calls D::operator=(const B&)
    

    指向派生实例的基指针正在调用虚拟函数=>调用多态性=>将调用派生版本。

    *bptr = 99; // ditto
    *bptr = dobj2; // ditto
    

    这很简单

    (*bptr).operator=(99);
    (*bptr).operator=(dobj2);
    

    或者,对派生实例的基引用正在调用虚拟函数=>调用多态性=>将调用派生版本。

    dobj1 = dobj2; // calls implicitly-declared D::operator=(const D&)
    

    没有更多多态性,因为调用方(dobj1)不是(基本)引用/指针。调用了D::运算符=(常量D&)由编译器生成,该编译器还调用 基类的运算符=自动。

    virtual B& operator= (const B&);
    
        2
  •  0
  •   Joseph D.    6 年前

    但我对*bptr=dobj2;不是很确定;。

    从…起 over.match.oper#tab:over.rel.op.func

    两者:

    *bptr = dobj2; // ditto
    dobj1 = dobj2; // calls implicitly-declared D::operator=(const D&)
    

    在上下文中相同,但表示方式不同:

    表示 :

    a=b
    

    作为成员函数 :

    (a).operator= (b)