2

I have a class with 2 public constructors, that I want to call a private constructor:

class CDeviceTSGetObservationResponse : public CDeviceServerResponse
{
public:
   /**
    * Public constructor. Used to construct a response containing
    * the required information from the TotalStation device.
    *
    * @param horizontalAngle
    *           The horizontal angle.
    * @param verticalAngle
    *           The vertical angle.
    * @param slopeDistance
    *           The slope distance.
    */
   CDeviceTSGetObservationResponse(double horizontalAngle, 
                                   double verticalAngle, 
                                   double slopeDistance)
       : CDeviceTSGetObservationResponse(CDeviceServerResponse::SUCCESS_MESSAGE,
                                         horizontalAngle,
                                         verticalAngle,
                                         slopeDistance) {}

   /**
    * Public constructor. Used to construct a response containing
    * the error message from the TotalStation device.
    *
    * @param errorMsg
    *           The error message for the response.
    */
   CDeviceTSGetObservationResponse(std::string errorMsg)
       : CDeviceTSGetObservationResponse(errorMsg,
                                         0.0,
                                         0.0,
                                         0.0) {}

private:
   /**
    * Private constructor.
    *
    * @param errorMsg
    *           The error message for the response.
    * @param horizontalAngle
    *           The horizontal angle.
    * @param verticalAngle
    *           The vertical angle.
    * @param slopeDistance
    *           The slope distance.
    */
   CDeviceTSGetObservationResponse(std::string errorMsg, 
                                   double      horizontalAngle, 
                                   double      verticalAngle, 
                                   double      slopeDistance) 
       : CDeviceServerResponse(CDeviceServerResponse::TS_GET_OBSERVATION, 
                               errorMsg),
         m_dHorizontalAngle(horizontalAngle), 
         m_dVerticalAngle(verticalAngle), 
         m_dSlopeDistance(slopeDistance){}

   /** The horizontal angle. */
   double m_dHorizontalAngle;

   /** The vertical angle. */
   double m_dVerticalAngle;

   /** The slope distance. */
   double m_dSlopeDistance;
}; // CDeviceTSGetObservationResponse

So the user will either call the constructor passing three booleans if there was no problem, and the error message on the baseclass will default to success.

Or they call the constructor passing in the error message, which will default the values to 0.0.

I thought I could do this with the code above, but I get the following error message:

camd011> make
g++ -c CDeviceTSGetObservationResponse.cpp \
        -I.. -o bin/CDeviceTSGetObservationResponse.o
In file included from CDeviceTSGetObservationResponse.cpp:13:0:
CDeviceTSGetObservationResponse.h: In constructor 'device::response::CDeviceTSGetObservationResponse::CDeviceTSGetObservationResponse(double, double, double)':
CDeviceTSGetObservationResponse.h:44:10: error: type 'device::response::CDeviceTSGetObservationResponse' is not a direct base of 'device::response::CDeviceTSGetObservationResponse'
CDeviceTSGetObservationResponse.h:47:55: error: no matching function for call to 'device::response::CDeviceServerResponse::CDeviceServerResponse()'
CDeviceTSGetObservationResponse.h:47:55: note: candidates are:
CDeviceServerResponse.h:72:4: note: device::response::CDeviceServerResponse::CDeviceServerResponse(device::response::CDeviceServerResponse::EServerMessageIdentifier, std::string)
CDeviceServerResponse.h:72:4: note:   candidate expects 2 arguments, 0 provided
CDeviceServerResponse.h:31:7: note: device::response::CDeviceServerResponse::CDeviceServerResponse(const device::response::CDeviceServerResponse&)
CDeviceServerResponse.h:31:7: note:   candidate expects 1 argument, 0 provided
CDeviceTSGetObservationResponse.h: In constructor 'device::response::CDeviceTSGetObservationResponse::CDeviceTSGetObservationResponse(std::string)':
CDeviceTSGetObservationResponse.h:57:10: error: type 'device::response::CDeviceTSGetObservationResponse' is not a direct base of 'device::response::CDeviceTSGetObservationResponse'
CDeviceTSGetObservationResponse.h:57:42: error: 'errorMeg' was not declared in this scope
CDeviceTSGetObservationResponse.h:60:45: error: no matching function for call to 'device::response::CDeviceServerResponse::CDeviceServerResponse()'
CDeviceTSGetObservationResponse.h:60:45: note: candidates are:
CDeviceServerResponse.h:72:4: note: device::response::CDeviceServerResponse::CDeviceServerResponse(device::response::CDeviceServerResponse::EServerMessageIdentifier, std::string)
CDeviceServerResponse.h:72:4: note:   candidate expects 2 arguments, 0 provided
CDeviceServerResponse.h:31:7: note: device::response::CDeviceServerResponse::CDeviceServerResponse(const device::response::CDeviceServerResponse&)
CDeviceServerResponse.h:31:7: note:   candidate expects 1 argument, 0 provided
CDeviceTSGetObservationResponse.cpp: In member function 'void device::response::CDeviceTSGetObservationResponse::serialize(Archive&, unsigned int)':
CDeviceTSGetObservationResponse.cpp:38:14: error: 'base_object' is not a member of 'boost::serialization'
CDeviceTSGetObservationResponse.cpp:38:69: error: expected primary-expression before '>' token
make: *** [bin/CDeviceTSGetObservationResponse.o] Error 1
4
  • do you want to use this(arguments) ? Commented Jul 3, 2013 at 17:47
  • The main error appears to be the: CDeviceTSGetObservationResponse.h:44:10: error: type 'device::response::CDeviceTSGetObservationResponse' is not a direct base of 'device::response::CDeviceTSGetObservationResponse' Commented Jul 3, 2013 at 17:47
  • Using this(arguments) gives the error: CDeviceTSGetObservationResponse.h:44:10: error: expected identifier before 'this' Commented Jul 3, 2013 at 17:49
  • Should : CDeviceTSGetObservationResponse(errorMeg, be : CDeviceTSGetObservationResponse(errorMsg, instead? In the middle constructor. Commented Jul 3, 2013 at 17:50

3 Answers 3

8

What you're looking for is delegating constructors and those are only available as of C++11.

For example:

struct A
{
    int x;

    A(): A(10) {}

private:    
    A(int val): x(val) {}
};

int main(int argc, char* argv[])
{
    A a;

    return 0;
}

As you can see here it compiles with C++11, but if you look here the same code does not compile (prior to C++11)

Sign up to request clarification or add additional context in comments.

1 Comment

The problem appears to be the Microsoft compiler. My code compiles OK on Unix with C++11, but Microsoft Visual Studio 12 is another matter. Ho...hum.
1

It's better to provide a normal private method instead of the private constructor, and call this one in the body of the other constructor definitions.

You can't use member initializer lists for such a private method of course, but initialize all the members as needed in the body of the method will do as well.

UPDATE:
Besides this, your error messages indicate you're using your class in some context that requires a default constructor.

Comments

-1

OK I removed the private constructor, and re-wrote the two public ones like this:

   /**
    * Public constructor. Used to construct a response containing
    * the required information from the TotalStation device.
    *
    * @param horizontalAngle
    *           The horizontal angle.
    * @param verticalAngle
    *           The vertical angle.
    * @param slopeDistance
    *           The slope distance.
    */
   CDeviceTSGetObservationResponse(double horizontalAngle, 
                                   double verticalAngle, 
                                   double slopeDistance)
       : CDeviceServerResponse(CDeviceServerResponse::TS_GET_OBSERVATION, 
                               CDeviceServerResponse::SUCCESS_MESSAGE),
         m_dHorizontalAngle(horizontalAngle), 
         m_dVerticalAngle(verticalAngle), 
         m_dSlopeDistance(slopeDistance) {}

   /**
    * Public constructor. Used to construct a response containing
    * the error message from the TotalStation device.
    *
    * @param errorMsg
    *           The error message for the response.
    */
   CDeviceTSGetObservationResponse(std::string errorMsg)
       : CDeviceServerResponse(CDeviceServerResponse::TS_GET_OBSERVATION, 
                               errorMsg),
         m_dHorizontalAngle(0.0), 
         m_dVerticalAngle(0.0), 
         m_dSlopeDistance(0.0) {}

1 Comment

Not sure why this was down-voted, as it provided what I required, without the nweed to write another unnecessary function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.