派生类中的C++赋值运算符

C++ assignment operator in derived class

本文关键字:C++ 赋值运算符 派生      更新时间:2023-10-16

我不太明白为什么对于赋值,派生类不调用基类的相应运算符,如果它自己的运算符不存在的话。看看代码:

#include <iostream>
using namespace std;
class A{
protected:
  void myWrite(){
    cout << " Base " <<endl;
  }
public:
  double x,y;
  A(): x{0},y{0}{};
  virtual A & operator=(double g){x=g;y=g;return *this;}
  virtual ~A(){};
  virtual void doneit(){myWrite();}
};

class B: public A{
protected:
public:
  B():A(){};
  virtual ~B(){};
  virtual void doneit(){myWrite();}
};
int main() {
  A jj;
  B pp;
  pp=0.0;
  return 0;
}

事实上,代码不会编译。当然,如果我为B定义了一个与A相同的"operator=",一切都可以,但如果派生类中的那个没有定义,为什么默认情况下不调用B"operator+"??你能帮我澄清一下这个问题吗?

gcc编译器说/src/tito.cpp:40:4:错误:没有可行的重载'='pp=0.0;~~^~~~../src/tito.cpp:28:7:注意:候选函数(隐式复制赋值运算符)不可行:第一个参数没有从"double"到"const B"的已知转换乙类:公共甲类{^生成1个错误。

你能解释一下为什么它不起作用吗?

如果不声明复制赋值运算符,编译器将为您声明一个。所以你的类B真的看起来像:

class B : public A {
public:
    // explicit
    B();
    virtual ~B();
    virtual void doneit();
    // implicit
    B(const B&);
    B& operator=(const B&);
};

隐式复制赋值运算符隐藏了您编写的A::operator=(double),因此它是名称查找将找到的唯一候选者。当然,它不是一个可行的候选者,因为double不能转换为B,因此出现了错误。

要使用A::operator=(double )运算符,必须明确地将其纳入范围:

using A::operator=;

但是,您不会分配任何B部分。所以最好更明确一点:

B& operator=(double g) {
    // B stuff here
    // A stuff
    A::operator=(g);
    return *this;
}
编译器隐式声明的派生类的复制赋值运算符隐藏基类的赋值运算符。以以下方式在派生类中使用using声明
class B: public A{
protected:
public:
  using A::operator =;     
  B():A(){};
  virtual ~B(){};
  virtual void doneit(){myWrite();}
};

另一种方法是在派生类中重新声明虚拟赋值运算符

B & operator=(double g) { A::operator =( g ) ;return *this;}

在这种情况下,您可以使用多态性。例如

#include <iostream>
class A
{
public:
  double x,y;
  A(): x{0}, y{0} {}
  virtual A & operator =( double g ){ x = g; y = g; return *this; }
  virtual ~A(){}
};

class B: public A
{
public:
  B() : A(){}
  virtual B & operator =( double g ) override { A::operator =( 2 * g ) ; return *this; }
  virtual ~B(){}
};
int main() 
{
    A a;
    B b;
    A *p = &a;
    *p = 10;
    std::cout << p->x << ' ' << p->y << std::endl; 
    p = &b;
    *p = 10;
    std::cout << p->x << ' ' << p->y << std::endl; 
    return 0;
}  

程序输出为

10 10
20 20