3

I'm adapting an existing library ("Webduino", a web server for Arduino) to work with another existing library ("WiFly", a wifi module) and running into a problem. Each library works fine on its own. The Webduino library expects to use an Ethernet hardware module over SPI, whereas the WiFi module uses a serial port (UART). The error I get is:

WiFlyClient.h: In member function 'WiFlyClient& WiFlyClient::operator=(const WiFlyClient&)':
WiFlyClient.h:14:
error: non-static reference member 'WiFlyDevice& WiFlyClient::_WiFly', can't use default assignment operator
WiFlyWebServer.h: In member function 'void WebServer::processConnection(char*, int*)':
WiFlyWebServer.h:492: note: synthesized method 'WiFlyClient& WiFlyClient::operator=(const WiFlyClient&)' first required here

Here are the relevant code snippets. Note that so far I have only been modifying WiFlyWebServer.h (Webduino):

// WiFlyWebServer.h (Webduino)
...
WiFlyServer m_server; // formerly EthernetServer and
WiFlyClient m_client; // EthernetClient
...
void WebServer::processConnection(char *buff, int *bufflen){
  ...
  // line 492
  m_client = m_server.available();
  ...
}



// WiFlyClient.h
class WiFlyClient : public Client {
 public:
  WiFlyClient();
  ...
private:
  WiFlyDevice& _WiFly;
  ...
}



// WiFlyClient.cpp
#include "WiFly.h"
#include "WiFlyClient.h"

WiFlyClient::WiFlyClient() :
  _WiFly (WiFly) {    // sets _wiFly to WiFly, which is an extern for WiFlyDevice (WiFly.h)
  ...
}


// WiFly.h
#include "WiFlyDevice.h"
...
extern WiFlyDevice WiFly;
...



// WiFlyDevice.h
class WiFlyDevice {
  public:
    WiFlyDevice(SpiUartDevice& theUart);
...



// WiFlyDevice.cpp
WiFlyDevice::WiFlyDevice(SpiUartDevice& theUart) : SPIuart (theUart) {
  /*

    Note: Supplied UART should/need not have been initialised first.

   */
  ...
}

The problem stems from m_client = m_server.available();, if I comment that out the problem goes away (but the whole thing relies on that line). The actual problem seems to be that the _WiFly member can't be initialized (overwritten?) when the WiFiClient object is being assigned, but I can't understand why it doesn't work here when it does work without modification.

(Yes, I know there's implementation in the header file, I don't know why they wrote it that way, don't blame me!)

Any insights?

T3db0t
  • 3,491
  • 4
  • 28
  • 45
  • `_WiFly` is [reserved](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) for the implementation. – chris Aug 17 '12 at 19:50
  • @chris, no, it is not defined in _global_ scope. To the question - why not just define your own assignment operator? Seems `_WiFly` should be just ignored there, as it initialized correctly in construction anyway – Lol4t0 Aug 17 '12 at 19:58
  • @Lol4t0, From the link: `Reserved in any scope, including for use as implementation macros: identifiers beginning with an underscore and an uppercase letter`. The global scope one is for starting with an underscore. – chris Aug 17 '12 at 19:59

3 Answers3

5

The WiFly member of your WiFlyClient is making the class not assignable. The reason for that is that assignment cannot be used to change which object the reference is referring to. For example:

int a = 1;
int b = 2;
int &ar = a;
int &br = b;
ar = br; // changes a's value to 2, does not change ar to reference b

Since all your WiFlyClients are referencing the same WiFlyDevice instance, you can change WiFlyClient as the compiler suggests to use a static member:

// WiFlyClient.h
class WiFlyClient : public Client {
 public:
  WiFlyClient();
  ...
private:
  static WiFlyDevice& _WiFly;
  ...
};

Then, you do not initialize it in the constructor, but in a source file where you define it.

WiFlyDevice & WiFlyClient::_WiFly = WiFly;
jxh
  • 69,070
  • 8
  • 110
  • 193
  • Thanks for this! I had already tried making _WiFly static, but hadn't experimented with where to properly define it. Now my code compiles, so time will tell if it functions properly... – T3db0t Aug 20 '12 at 19:44
0

Clearly the problem is that WiFlyClient is not assignable. Consider containing it in a std::unique_ptr (in C++03, std::auto_ptr) so that you can at least assign items of that type.

std::unique_ptr<WiFlyClient> m_client;

...

m_client = m_server.available();

...

// convert m_client.<...> to m_client-><...>

// change m_server.available() to return std::unique_ptr<WiFlyClient>
ecatmur
  • 152,476
  • 27
  • 293
  • 366
0

Try overriding operator=:

WiFlyClient& operator= (const WiFlyClient & wi)
{
  /* make a copy here */ 
  return *this;
}
jogojapan
  • 68,383
  • 11
  • 101
  • 131
Bruno Romano
  • 303
  • 2
  • 10
  • I looked into this and tried a couple things but I couldn't figure out the right recipe for making the copy... – T3db0t Aug 19 '12 at 14:36