繁体   English   中英

基类中的重载赋值运算符

[英]Overloading Assignment Operator in Base Class

我有一个名为BaseSignal的模板化类,

  template <class T>
  class BaseSignal
  {
    public:
    // Constructor
    BaseSignal(long buf_size, bool is_async, SimData *sim)
    ....

从该类派生另外两个模板化类NetReg (对于那些感兴趣的人,我正在Verilog中对并发和顺序分配的行为进行建模)。 这些被定义为

  template <class T>
  class Net : public BaseSignal<T>
  {
    public:
    Net(long buf_size, bool is_async, SimData* sim)
      : BaseSignal<T>(buf_size, is_async, sim) {};
      ....

和类似的Reg

在基类中,我将SetGet方法定义为虚拟方法,

    // Virtual settors
    virtual void Set(long val) {};
    virtual void Set(double val) {};

    // Virtual gettors
    virtual void Get(long* val) const {};
    virtual void Get(double* val) const {};

由于NetReg具有不同的行为。 所以这是有趣的部分。

+ =基类中的重载工作

在基类中,我定义了此运算符以调用虚拟的SetGet操作,该操作可以按预期工作。

BaseSignal

    BaseSignal<T>& operator+=(const double& rhs)
    {
      T rval;
      this->Get(&rval);
      this->Set(rval + static_cast<T>(rhs));
      return *this;
    }
    BaseSignal<T>& operator+=(const long& rhs)
    {
      T rval;
      this->Get(&rval);
      this->Set(rval + static_cast<T>(rhs));
      return *this;
    }

在我的代码中,我有指针net_realnet_int ,当我这样做时

  *net_real += 1.1;
  *net_int += 1l;

净值正确增加。 这是奇怪的部分

=重载在基类中不起作用

如预期的那样, Net类中的Overloading =可以正常工作:

    Net<T>& operator=(const double& rhs)
    {
      this->Set(static_cast<T>(rhs));
      return *this;
    }
    Net<T>& operator=(const long& rhs)
    {
      this->Set(static_cast<T>(rhs));
      return *this;
    }

但是如果我把它放在BaseSignal

    BaseSignal<T>& operator=(const double& rhs)
    {
      this->Set(static_cast<T>(rhs));
      return *this;
    }
    BaseSignal<T>& operator=(const long& rhs)
    {
      this->Set(static_cast<T>(rhs));
      return *this;
    }

我可以很好地编译类文件,但是当我编译main.cpp ,我得到了:

ctests/main.cpp: In function 'int main()':
ctests/main.cpp:28:15: error: no match for 'operator=' (operand types are 'cpysim::Net<double>' and 'double')
   28 |   *net_real = 1.0;
      |               ^~~
In file included from ctests/main.cpp:9:
csrc/signals_nets.hpp:456:9: note: candidate: 'constexpr cpysim::Net<double>& cpysim::Net<double>::operator=(const cpysim::Net<double>&)'
  456 |   class Net : public BaseSignal<T>
      |         ^~~
csrc/signals_nets.hpp:456:9: note:   no known conversion for argument 1 from 'double' to 'const cpysim::Net<double>&'
csrc/signals_nets.hpp:456:9: note: candidate: 'constexpr cpysim::Net<double>& cpysim::Net<double>::operator=(cpysim::Net<double>&&)'
csrc/signals_nets.hpp:456:9: note:   no known conversion for argument 1 from 'double' to 'cpysim::Net<double>&&'

我不确定100%是否了解“候选”部分。 是否尝试调用复制构造函数? 而且我也不明白为什么与操作(operand types are 'cpysim::Net<double>' and 'double')不匹配(operand types are 'cpysim::Net<double>' and 'double') ,因为Net源自BaseSignal ,并且我为这些操作数定义了运算符。 更令人困惑的是为什么它适用于+=而不适用于=

这是一个隐藏名称的问题; 派生类具有隐式生成的operator= s,包括复制赋值运算符移动赋值运算符 ,它们隐藏了基类的operator= s。

这就是名称查找的工作方式。 当在派生类作用域中找到名称operator=时,将不检查包括基类作用域在内的其他作用域,名称查找将停止。 之后,根据找到的名称执行重载解析,最后导致编译错误。

operator+=没有这个问题; 在派生类中没有(隐式或显式)声明operator+=

您可以使用using将基类的operator=引入派生类范围。 例如

template <class T>
class Net : public BaseSignal<T>
{
  public:
    using BaseSignal<T>::operator=;
  ...
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM