is it a good idea to use a static method to check arguments before calling constructor?

Hello,

I personally don't like that syntax and semantics of C++ don't support constructor returning failure. But my understanding of the reasons behind it are probably shallow and I am probably incorrect.

OK, nevertheless, I would like to avoid throwing things in constructors as much as possible.

Is this good design to have a static class method that checks arguments the caller will give to the constructor. The documentation of the class will say, thou shall call this method to validate thine arguments before calling the constructor, or else segfault may befall thoust.

Thank you for your opinion,

Mark
You should opt to design things in such a way that it is not possible to give bad parameters in the first place. Exceptions are for exceptional cases, not for when someone tries to intentionally deliver a bad parameters.
Last edited on
Thank you for your reply. Can you elaborate, so I can better understand you?

For example, right now I am implementing a class that chooses an element of std::vector<T> according to some algorithm, and the user can specify the index of the first element chosen.

Thus the class has private members storing the vector and the choice of first index, and these are initialized by an initializer list in the constructor. But then in the constructor body, I need to make sure the unsigned argument that the caller gave (the first index) is less than the size, and then throw up if not.

How can I design it so the caller cannot deliver two arguments which are in conflict with each other (first index not less than the size of the vector).

It seems I have to either throw up, or provide the method to the caller to check.

The caller does not "intentionally" provide bad arguments. In software engineering, you never intentionally bug. Yet, we all bug all the time. ("Bugging" being the reverse of "debugging" - the activity of putting bugs in the code).

Mark
MarkGaleck wrote:
I am implementing a class that chooses an element of std::vector<T> according to some algorithm, and the user can specify the index of the first element chosen.

Thus the class has private members storing the vector and the choice of first index, and these are initialized by an initializer list in the constructor. But then in the constructor body, I need to make sure the unsigned argument that the caller gave (the first index) is less than the size, and then throw up if not.

How can I design it so the caller cannot deliver two arguments which are in conflict with each other (first index not less than the size of the vector).

It seems I have to either throw up, or provide the method to the caller to check.
I think this is a design problem more than anything. Why do you need a whole class for a single-use algorithm? Why aren't you validating user-input in the first place?

Always validate user-input before using it in any way.

MarkGaleck wrote:
The caller does not "intentionally" provide bad arguments. In software engineering, you never intentionally bug. Yet, we all bug all the time. ("Bugging" being the reverse of "debugging" - the activity of putting bugs in the code).
The goal is to write code for which it is very difficult to create bugs which your compiler will not catch.
Last edited on
I would like to avoid throwing things in constructors as much as possible.

Sounds like C++ is not the best fit for your goals. Is there a reason other than personal dislike?
Last edited on
The main reason is that exceptions in general, or at least in every programming language I have seen, are poorly implemented, cause more problems than they solve, have an ugly syntax, and are unbearably slow. That's why they are only used in truly exceptional cases, which generally tend to be cases you shouldn't handle anyway, such as running out of memory - a wrapper would handle that.
Last edited on
This is a strange case but there's two ways to look at this:

1) If you want exceptions, I usually suggest putting them in debug blocks simply so that you are not using unbearably slow, poorly implemented code in release.

1
2
3
#ifdef _DEBUG
     throw(exception);
#endif 


2) The client should be checking for incorrect usage of parameters, however the class is responsible for not creating actual crashes. I would simply error check your value.

1
2
if(unFirstIndex >= v.size())
     unFirstIndex = 0;
L B is asking

"Why do you need a whole class for a single-use algorithm"

It's not single use... it's like rand(), you seed it once, then it returns things to you according to some algorithm. Similar... rand() probably uses some static variable... Since this is C++, I can have a class, so I can have several instances of "rand", each with it's own state.

Anyway, that was not my question, "do I need my class or not". My question was, assuming I need it, how to make it robust?


"why aren't you validating user-input in the first place".

Well, it's not me... I am designing a class, and will provide a public interface for it. The caller of that class, well that's not me, somebody will call it and I don't have control over that code.

So then, I want to make my class as robust as possible. Then the question is, how to check the arguments, throw up in the constructor, or perhaps provide the caller with a static method to check their arguments.


Cubbi asks :
"is there a reason"

No. I just think that there should be a way (syntax and semantics) in C++ to fail the constructor (the effect would be just as throwing - no object is constructed), so the caller can check the "return", rather than doing try and catch.

Convince me this is a deep reason why there isn't such a feature in the language.

Thank you,

Mark



What is this, 1992?
Instead of having the constructor take an index and the vector, have the constructor take an iterator. If the iterator is invalid, that's not your fault, and you shouldn't handle it. Never try to handle external errors.

MarkGalek wrote:
I just think that there should be a way (syntax and semantics) in C++ to fail the constructor (the effect would be just as throwing - no object is constructed), so the caller can check the "return", rather than doing try and catch.
So you want a different syntax rather than a different semantic.

Constructors shouldn't fail, and when they do, you shouldn't try to handle that - they failed for a very good reason.

@Cubbi actually it's 1994 for you.
Last edited on
there should be a way (syntax and semantics) in C++ to fail the constructor

That is called throwing an exception. It's one of the fundamental features of C++ that makes it robust, safe, and efficient.
+1 @ Cubbi.

Get over your fear/dislike of exceptions and learn to use them properly. They're awesome.
> Always validate user-input before using it in any way.
The best one for validate is an object of that class.
It known what is `valid'

> Instead of having the constructor take an index and the vector, have the constructor take an iterator.
¿how is that any different?

> thou shall call this method to validate thine arguments before calling the constructor
error prone


An alternative is to provide an `ok' flag that determines if the object is valid.
Operating on an invalid object is a logic error.
By instance `std::fstream'
ne555 wrote:
> Instead of having the constructor take an index and the vector, have the constructor take an iterator.
¿how is that any different?
An iterator is more likely to be valid, it is more generic than this specific use-case, and it has its own debug assertions.
> An iterator is more likely to be valid
Nope.
You may construct it invalid (default constructor)
You may use a valid one, from another container
There are operations that invalidate iterators (like insert and erase)
It's as faulty as an index

> it is more generic than this specific use-case
Agreed.

> and it has its own debug assertions.
¿what do you mean?
`.at()' and `_GLIBCXX_DEBUG'
Topic archived. No new replies allowed.