I am having a strange issue with overloading the assignment operator in an inherited class. My code has the following relevant pieces
class BaseSignal
{
  ...
  virtual void Get(double* val) const {};
  virtual void Set(double val) {};
  BaseSignal& operator=(const BaseSignal& other);
  BaseSignal(const BaseSignal& orig);
  ...
}
BaseSignal& BaseSignal::operator=(const BaseSignal& other)
{
  double dval;
  other.Get(&dval);
  this->Set(dval);
}
template <class T>
class Net : public BaseSignal
{
  ...
  using BaseSignal::operator=;
  T* pval_;
  ...
  void Set(T val)
  {
    *pval_ = val;
  }
}
I don't think that the fact that the derived class is a template matters here.
The problem I'm having is when I evaluate the final equality in the sequence below:
Net<double>* net_real = new Net<double>(...);
*net_real = 1.0;
Net<double>* net_real2 = new Net<double>(...);
*net_real2 = 3.0;
*net_real = *net_real2;
Stepping through the code, all the virtual functions are followed, and indeed the value pointed to by pval_ of net_real gets updated to 3.0 when the Net<double>::Set method is called by the overloaded = operator. The problem is that when I return from the call stack to the next line after *net_real = *net_real2;, it looks like somehow a shallow copy of net_real2 was performed. Specifically, the pointer pval_ in net_real now suddenly has the same address as the pointer in net_real2.
Is somehow the overloaded base = operator called, THEN the implicit = operator of the derived class being called? I have not defined any equality/copy constructor of the derived class (but there is an explicitly-defined copy constructor of the base class).
EDIT
I've pasted a block of code below that shows what's going on. I stripped a lot of stuff out, but I hope this shows the problem. I just ran this in [cpp.sh].
// Example program
#include <iostream>
#include <string>
  class BaseSignal
  {
    public:
    /**
     * Constructor and destructor methods
     */
    // Nullor
    BaseSignal() {};
    // Destructor
    virtual ~BaseSignal() {};
    // Copy
    BaseSignal(const BaseSignal& orig);
    // Virtual settors
    virtual void Set(double val) {};
    // Virtual gettors
    virtual void Get(double* val) const {};
    // Equality to another signal
    BaseSignal& operator=(const BaseSignal& other);
    BaseSignal& operator=(const double& rhs);
  }; // class BaseSignal
  BaseSignal& BaseSignal::operator=(const double& rhs)
  {
    this->Set(rhs);
    return *this;
  }
  // Equality to another signal. Check vector widths are equal
  BaseSignal& BaseSignal::operator=(const BaseSignal& other)
  {
    std::cout << "******BaseSignal::operator= was called!******\n";
    double dval;
    other.Get(&dval);
    this->Set(dval);
    return *this;
  }
template <class T>
  class Net : public BaseSignal
  {
      public:
    T* pval_;
    /**
     * Constructors/destructors
     */
    Net() : BaseSignal()
    {
      // Initialize value
      pval_ = new T[1]{0};
    }
    ~Net() {delete[] pval_;}
    /**
     * Operator Overloads
     */
    using BaseSignal::operator=;
    /**
     * Setting with a constant value input just writes to the value at pval_.
     * If the Net is a 2-D vector, this method writes all values in the vector
     * to be the same val.
     */
    void Set(T val)
    {
        pval_[0] = val;
    } // Net<T>::Set
    /**
     * The Get method returns the number of elements based on the col_
     * parameter.
     */
    void Get(T* val) const
    {
        val[0] = pval_[0];
    } // Net<T>::Get
};
int main()
{
    double read_val;
    Net<double>* net_real = new Net<double>();
    *net_real = 1.0;
    net_real->Get(&read_val);
    std::cout << "net_real is equal to: " << read_val << "\n";
    std::cout << "net_real has pval_ pointer: " << net_real->pval_ << "\n";
    Net<double>* net_real2 = new Net<double>();
    *net_real2 = 2.0;
    net_real2->Get(&read_val);
    std::cout << "net_real2 is equal to: " << read_val << "\n";
    std::cout << "net_real2 has pval_ pointer: " << net_real2->pval_ << "\n";
    std::cout << "Now assigning value of net_real2 to net_real\n";
    *net_real = *net_real2;
    net_real->Get(&read_val);
    std::cout << "net_real is now equal to: " << read_val << "\n";
    std::cout << "net_real now has pval_ pointer: " << net_real->pval_ << "\n";
}
 
    