class item
{
int i;
public:
item(int no) {
}
};
I want to check the constructor parameter. If it is found to hold a negative value, then object creation should be stoppe开发者_如何学运维d.
Exceptions can not be used here as the targeted system does not support exceptions.
There is no way to stop the creation of an object without throwing. The best you can do is set an "invalid parameter" flag that you have to check afterwards, and if true discard the object without using it.
With the requirements you have, it would probably be better to use a factory method to create the objects -- this way, you can make the checks before calling the constructor:
class item
{
int i;
public:
static item* create(int no) {
if (no < 0) {
return 0;
}
return new item(no);
}
private:
item(int no) {
}
};
You could use this like
item* myItem = item::create(-5);
if(!myItem) {
// failed
}
However, this forces you to allocate all item
instances on the heap.
Exceptions are the way designated by the standard to perform this task; there's no other way to abort completely the object creation.
On the other hand, you can give your class some "state" member that specifies that the class was not correctly constructed and check it at every method call (a bit like how iostream
classes work).
class item
{
int i;
bool validState;
public:
item(int no) : validState(true)
{
if(/* no is invalid */)
{
validState = false;
return;
}
/* ... */
}
bool ValidState() { return validState; }
SomeType DoSomething()
{
if(!ValidState())
{
// do nothing/report the error to the caller
}
// ...
}
}
IMO it's cumbersome, but if you don't have exceptions and want to create objects via a public constructor there's nothing much better than this.
You cannot stop object construction mid-way, without throwing an exception. That said, you may outright prevent construction of item objects which fail a precondition, by moving the precondition and object-creation responsibilities to a separate factory function, and making the constructors private (to disallow all other ways to construct the object):
class item {
int i;
public:
static item* create( int no )
{
return no < 0 ? NULL : new item( no );
}
private:
item() { ... }
item( int no ) { ... }
};
Three options.
- Use a flag in your class to track full construction - but you'll have to test that in each method.
- Make
item
a wrapper, such that the internals are held in a class that is constructed if the arguments are good, but in all the methods, you'll have to test the internals - so no different to 1 anyway. - Use a factory to return a smart pointer if the arguments are good.
My preference in this scenario is the last one.
Put the object into an error state (use a boolean) and then all methods should return an error.
ie
class Item
{
int i;
bool errorState;
public:
Item(int n) : i(n) {
errorState = i < 0;
}
bool method()
{
if (errorState) return false;
..... do stuff here
return true;
}
}
You can do it at compile time with necessary warning flags ON (e.g. -Wall
in gcc).
class item
{
public:
item(unsigned int no) {} // item takes only +ve value
};
Compiler will warn you if a -ve
value is passed.
精彩评论