diff --git a/CHANGELOG.md b/CHANGELOG.md index 74df5b83..a88daee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Change 266 files from CRLF to LF. - Run tests on push as well as on a pull request so developers can see impact +- Apply "rule of three" to Client copy constructor and copy assignment operator ### Deprecated diff --git a/SampleProjects/TestSomething/test/clientServer.cpp b/SampleProjects/TestSomething/test/clientServer.cpp index f088c821..7ffa2d6a 100644 --- a/SampleProjects/TestSomething/test/clientServer.cpp +++ b/SampleProjects/TestSomething/test/clientServer.cpp @@ -19,6 +19,29 @@ unittest(Client) { assertEqual(outData + "\r\n", inData); } +unittest(Client_copy_constructor) { + { // Client object contains a reference to a String object + Client c1; // Constructor instantiates a String (string1) + Client c2; // Constructor instantiates a String (string2) + c1.write('1'); + c2.write('2'); + assertEqual("1", *(c1.mGodmodeDataIn)); + assertEqual("2", *(c2.mGodmodeDataIn)); + c2 = c1; // c2 should get a copy of s1, not a reference to it + // and string2 should have been deleted during the assignment + assertNotEqual(c1.mGodmodeDataIn, c2.mGodmodeDataIn); + assertEqual("1", *(c1.mGodmodeDataIn)); + assertEqual("1", *(c2.mGodmodeDataIn)); + c1.write('1'); + c2.write('2'); + assertEqual("11", *(c1.mGodmodeDataIn)); + assertEqual("12", *(c2.mGodmodeDataIn)); + } // End of scope calls destructor on c1 and c2 + // Memory monitoring will give an error if delete is called twice on string1 + // The following assertion is just to confirm that we got through the above + assertTrue(true); +} + unittest(IPAddress) { IPAddress ipAddress0; assertEqual(0, ipAddress0.asWord()); diff --git a/cpp/arduino/Client.h b/cpp/arduino/Client.h index 154e618d..759267a4 100644 --- a/cpp/arduino/Client.h +++ b/cpp/arduino/Client.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include class Client : public Stream { public: @@ -11,6 +11,25 @@ class Client : public Stream { mGodmodeDataIn = new String; } } + Client(const Client &client) { // copy constructor + if (this != &client) { // not a self-assignment + if (mGodmodeDataIn && + client.mGodmodeDataIn) { // replace what we previously had + delete mGodmodeDataIn; // get rid of previous value + mGodmodeDataIn = new String(client.mGodmodeDataIn->c_str()); + } + } + } + Client &operator=(const Client &client) { // copy assignment operator + if (this != &client) { // not a self-assignment + if (mGodmodeDataIn && + client.mGodmodeDataIn) { // replace what we previously had + delete mGodmodeDataIn; // get rid of previous value + mGodmodeDataIn = new String(client.mGodmodeDataIn->c_str()); + } + } + return *this; + } ~Client() { if (mGodmodeDataIn) { delete mGodmodeDataIn;