0

I have a base class called Socket, then subclass called RwSocket, and a subclass to that called RoSocket.

I push_back into a std::vector the instances of the two subclasses, and see the copy constructor getting invoked. However when I push either one only, then no copy constructor is invoked, only move constructor. I never want the copy constructor to get invoked.

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;


class SocketInterface
{
  public:
  SocketInterface(const std::string &name)
   : m_name(name)
  {
    cout << m_name << " ctor" << this << endl;
  }
  SocketInterface(const std::string &&name)
     : m_name(std::move(name))
  {
    cout << m_name << " ctor2" << this << endl;
  }
  virtual ~SocketInterface()
  {
    cout << m_name << " dtor" <<  this << endl;
  }
  SocketInterface(const SocketInterface&rhs)
     : m_name(rhs.m_name)
  {
     cout << m_name << " cptor&" <<  this << endl;
  }
  SocketInterface(const SocketInterface&&rhs)
     : m_name(std::move(rhs.m_name))
  {
     cout << m_name << " mvtor&&" <<  this << endl;
  }
  virtual void write(const std::string&) const = 0;
  virtual std::string read() const = 0;

  protected:
  std::string m_name;
};

class RwSocket : public SocketInterface
{
  public:
  RwSocket(const std::string &name)
  : SocketInterface(name) {}
  virtual ~RwSocket() {}
  RwSocket(const RwSocket&rhs)
     : SocketInterface(rhs)
  {}
  RwSocket(const RwSocket&&rhs)
     : SocketInterface(std::move(rhs))
  {}

  virtual void write(const std::string &message) const override
  {
    cout << m_name << " " << this << " " << message << endl;
  }
  virtual std::string read() const override
  {
    std::stringstream ss;
    ss << std::hex << this;
    auto self = ss.str();
    return m_name + " " + self + " did read something";
  }
};

class RoSocket : public RwSocket
{
  public:
   RoSocket(const std::string &name)
   : RwSocket(name)
   {}
   virtual ~RoSocket() {}
   RoSocket(RoSocket&rhs)
      : RwSocket(rhs)
   {}
   RoSocket(const RoSocket&&rhs)
      : RwSocket(std::move(rhs))
   {}

  virtual void write(const std::string &message) const override
  {
  }

  virtual std::string read() const override
  {
    return RwSocket::read();
  }

};

void work(std::vector<RwSocket> &&sockets)
{
  for(auto&& socket : sockets)
  {
    socket.write("writing outgoing message");
    cout << socket.read() << endl;
  }
}

int main(int argc, char *argv[])
{
   std::vector<RwSocket> sockets;
   sockets.emplace_back(std::move(RoSocket("ro")));
   sockets.emplace_back(std::move(RwSocket("rw")));
   work(std::move(sockets));
   return;
}

Output:

ro ctor0x7fff9752a120
ro mvtor&&0x1f8c590
ro dtor0x7fff9752a120
rw ctor0x7fff9752a180
rw mvtor&&0x1fa2bb8
ro cptor&0x1fa2b90
ro dtor0x1f8c590
rw dtor0x7fff9752a180
ro 0x1fa2b90 writing outgoing message
ro 0x1fa2b90 did read something
rw 0x1fa2bb8 writing outgoing message
rw 0x1fa2bb8 did read something
ro dtor0x1fa2b90
rw dtor0x1fa2bb8

But when I comment out either one of these

   sockets.emplace_back(std::move(RoSocket("ro")));
   sockets.emplace_back(std::move(RwSocket("rw")));

then the copy constructor does not get invoked.

Why is the copy constructor getting called if I push more than once?

rosewater
  • 604
  • 2
  • 8
  • 22

0 Answers0