I have a class and in the class constructor I want to check few parameters that have been passed, if any parameter fails the check, I want to prevent the class from initialisation. How can I do that ?
Class MyClass
{
MyClass(int no);
};
MyClass::MyClass(int no)
{
开发者_如何学Cif(no<0) // Prevent the Class from Initialisation
}
void main()
{
MyClass myobj(-1);
// How to check if myobj is an objecT???
// if(myobj!=null) ???
}
Throw an exception.
In your specific case: take an unsigned int
.
In general: throw an exception.
If we were to mention all possibilities:
By allowing zombi objects, user shouldn't do anything with them unless he has called a function like is_good
and found that it returned true:
Class MyClass
{
public:
MyClass(int no);
bool is_good() const { return good; }
private:
bool good;
};
MyClass::MyClass(int no): good(no >= 0)
{
}
int main()
{
MyClass m(100);
if (m.is_good()) {
//Go ahead and use it
}
}
Technically it would be possible to add runtime checks that the instance is not used unless is_good()
was called and returned true.
This is the approach iostreams have taken.
Some people would also mention out parameters for the constructor (gets weirder and weirder):
Class MyClass
{
public:
MyClass(int no, bool& success);
};
MyClass::MyClass(int no, bool& success)
{
success = no >= 0;
}
int main()
{
bool result;
MyClass m(10, result);
if (result) {
//go ahead and use m
}
}
Personally I find this a bit too awkward.
Neither of those prevent creation of an instance. Only throwing an exception can really abort object construction, so it is never completed.
You could make your class have a private constructor, and a public function called "getInstance". When you call getInstance, it does the check and returns null if the check is bad. If your check is ok and you want to instantiate the class, getInstance will create and return a new instance.
It really does depend on what you're doing and why. You might find that your checking process is actually better done in a separate class. Anyway, here are some suggestions:
- Throw an exception as mentioned earlier. Need to ensure all your calling code is exception safe though.
- Use an
init()
function to do the actual initialization. This is useful if you've a number of constructors or want to call a pure virtual function, but it doesn't much help other than to allow you to structure your code in stages (i.e. you could avoid callinginit()
if early checks fail and mark the object as invalid. - You could use placement new and bail out early if checks aren't met though these would obviously be outside the constructor.
Like I said it all depends on what you want to do.
精彩评论