7

I have a member of class A in my own class which constructor takes multiple parameters. Im forwarding parameters of my own class to the constructor of class A. But its important that these parameters are correct, so i need to check them before consructing the member of A. And heres the problem: I could leave out the member in the member intialization list, effectively calling the default constructor. After the checks in the constructor i could then call A`s constructor in a assigment. Although, this produces a error since the destructor of A is private.

How do i solve this?

MyClass::MyClass(int someParam) : otherMember(2){
//checks for someParam
member = A(someParam); // <- produces error
}
Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
  • Talk to the author of class `A` and coerce her to make `A`'s own constructor behave sensibly in the event of illegal parameter values. – Kerrek SB Jan 01 '12 at 23:26
  • Would it be acceptable to construct `A` and then check after the fact? – Cameron Jan 01 '12 at 23:26
  • I actually tried to persuade Sun to make this acceptable in Java, but they refused. It's slightly easier to cheat in Java because you can call one constructor from another. – Neil Jan 02 '12 at 00:10

2 Answers2

10

You're going to need an accessible destructor no matter what you do. But to address your question, one option would be to call a static function to check parameters from within the initializer:

class MyClass {
  private:
    static void checkParam(int);
// ...
};

MyClass::MyClass(int someParam) : otherMember( (checkParam(someParam), 2) ) {
  // ...
}

static void MyClass::checkParam(int someParam) {
  if (...) throw someException();
}

Note that the , used there is the comma operator, not an argument separator - it evaluates both left and right expressions, and throws away the result of the left.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • Would exceptions thrown in checkParam() still interrupt programflow? If the answer to this question is yes, this is exactly what i need. For those of you who are wondering about the private destructor, its a reference counted objected; I gueess using the appropiate reference counting pointer would be better. – Sebastian Hoffmann Jan 02 '12 at 00:09
  • Yes. checkParam will be evaluated before `2`, so if it throws, `2` will not evaluate, and thus `otherMember`'s constructor cannot be invoked – bdonlan Jan 02 '12 at 00:11
0

I see two ways of approaching this:

  1. Make sure class A can be used with a parameter-less constructor, and set someParam in a separate method: A.SetSomeParam(someParam)

  2. Not inherit from A, but rather hold a member object of type A, and then you can construct it whenever you like.

Ilya Kogan
  • 21,995
  • 15
  • 85
  • 141