2

Is it possible to check the arguments of a constructor for certain constraints and if they're not met the object is not created and return a value to tell it failed to be created .

for instance .

Class Device
{
   string id;
   Device(string ID)
   {
          If (ID.Length != 7)
          {
              //Do not create Object
          }
    id == ID;
   }

}

Here I only want 7 char long id String , not less not more ! if its not 7 char I don't want the Object created is it possible to do this ?

I couldn't think of any solution to this other than external function check which is something I want to stay away from !

Cœur
  • 37,241
  • 25
  • 195
  • 267
Malek
  • 1,321
  • 2
  • 8
  • 11
  • 3
    You could throw an exception. Using an external function is a cleaner way though with less potential problems. – kfx Jan 05 '16 at 17:27
  • It would be useful to see the caller code that use what you want – Edwin Rodríguez Jan 05 '16 at 17:29
  • @kfx yes indeed an exception would solve this problem . will need a try and catch but will work great . thanks ! I didnt want an external function because without it my object can hold wrong data by mistake which is something I do not want ! – Malek Jan 05 '16 at 17:36
  • If you didn't need to take a std::string as the parameter but rather 7 characters you could make use of templates and make it so if not exactly 7 characters it wouldn't even compile. – A.J. Jan 05 '16 at 20:20

5 Answers5

6

The usual way would be to check the condition, and if it's not met, throw an exception.

Another possibility would be to accept an array of 7 characters, so the code won't compile if something else is passed. This tends to be trickier to get to work well in general though (e.g., it usually won't work if somebody passes an object of the wrong type, even something like a string that actually does contain 7 characters).

A sort of intermediate point would be to create a type specifically to hold your string of 7 characters, and throw an exception in its ctor if the length is wrong. This can give a little more granularity so it's easier to know what's wrong when the exception is thrown, as well as assuring that creating the Device object will succeed if you pass it a valid DeviceName (or whatever name you prefer) object.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • but wouldn't using the first method ( throwing an exception and catching it ) be a better and easier choice by defining a special exception for this case ? – Malek Jan 05 '16 at 17:45
  • @Malek: you certainly *can* define your own exception. If you do, it should probably derive from `std::invalid_argument` unless you have a specific reason to do otherwise. Whether that's better and easier than the alternatives will depend on the situation. – Jerry Coffin Jan 05 '16 at 17:50
  • Good points ! thank you for your help ! solved my problem – Malek Jan 05 '16 at 17:52
2

You can throw an exception. https://stackoverflow.com/a/7894215/2887128

Class Device
{
   string id;
   Device(string ID)
   {
          If (ID.Length != 7)
          {
              throw invalidObjectParametersException;
          }
    id == ID;
   }

}

You could also adjust your design and wrap construction in some sort of factory.

Community
  • 1
  • 1
jaredready
  • 2,398
  • 4
  • 23
  • 50
1

One option I can think of is to throw an error if the condition is not met and catch that error in the function that creates the object.

0

Yes, you can implement a valid method, which will return if the created object is valid. In order to do that, without creating your real object, you would have to create an internal struct, which would become a private member of the owner class:

Class Device
{
   struct DeviceImplementation {
      string id;
      Device owner;
      DeviceImplementation (Device *owner, const string &id):
        owner(owner),
        id(id)
      {
      }
   };
   std::unique_ptr<DeviceImplementation> implementation;
public:
   Device(const string &ID)
   {
          If (ID.Length != 7)
          {
              //Do not create Object
          } else
            implementation=std::unique_ptr<DeviceImplementation>(new DeviceImplementation(this, ID));
   }

   bool isValid() const {return implementation!=nullptr;}
}
LoPiTaL
  • 2,495
  • 16
  • 23
-1

No, a constructor can only return an object (or raise an exception).

If you want the chance to verify parameters or context, you should make:

a) the constructor private (so it cannot be called from outside the class anymore)

b) provide a static public method that returns an object (or, for example, NULL if it failed), and inside this method do your tests, and if they are successful call the private constructor and return the created object.

Of course, the outside code needs to able to handle a NULL return (or whatever you chose to do to signal that it failed).

This is a simple and common solution, but you can make up others with similar ideas.

Aganju
  • 6,295
  • 1
  • 12
  • 23