Reputation: 11502
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
}
Upvotes: 8
Views: 1618
Reputation: 5231
Another way to check before the construction is to make the constructor private and check before calling it:
# include <cassert>
class Foo
{
private:
int x;
int y;
public:
Foo(int x_, int y_);
private:
struct InitCheckDone {};
Foo(InitCheckDone, int x_, int y_);
};
Foo::Foo(int x_, int y_) : Foo((
assert(x_ >= 1),
assert(y_ >= 1),
assert(x_ + y_ <= 20),
InitCheckDone()), x_, y_) {}
Foo::Foo(InitCheckDone, int x_, int y_) :
x(x_),
y(y_)
{}
int main()
{
Foo f1(3,3);
Foo f2(12,17);
return 0;
}
Upvotes: 0
Reputation: 22389
I see two ways of approaching this:
Make sure class A
can be used with a parameter-less constructor, and set someParam
in a separate method: A.SetSomeParam(someParam)
Not inherit from A
, but rather hold a member object of type A
, and then you can construct it whenever you like.
Upvotes: 0
Reputation: 231343
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.
Upvotes: 11