Don't allow empty object in vector

Sep 14, 2012 at 4:06pm
What can I do to prevent the user from just create an empty object?

This is an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class myClass
{
    public:
        
        string Foo;
        string Bar;

        void createObject()
        {
            cout << "Enter first string: " << endl;
            getline(cin, Foo);

            cout << "Enter second string: " << endl;
            getline(cin, Bar);

            return Foo, Bar;
        }
};


As it is now the user can press enter without typing anything and I do not want the user to be able to create objects without these values.

I fought about an if, something like if(Foo != "" || Bar != "") but I don't know where to put it, and what to return if the user has not made an input.

I would like it to loop back and let the user try again, but I need help with this...

Thanks in advance
Sep 14, 2012 at 4:22pm
Try the following code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <string>
#include <iostream>

class myClass
{
    private:
        myClass( const std::string &Foo, const std::string &Bar ) : Foo( Foo ), Bar( Bar ) {}
        std::string Foo;
        std::string Bar;

    public:
        static myClass createObject()
        {
            std::string Foo;

            do
            {
                std::cout << "Enter first non-empty string: " << std::endl;
                std::getline( std::cin, Foo );
            } while ( Foo.empty() );

            std::string Bar;

            do
            {
                std::cout << "Enter second non-empty string: " << std::endl;
                std::getline( std::cin, Bar );
            } while ( Bar.empty() );

            return ( myClass( Foo, Bar ) );
        }
};


int main()
{
    myClass m1 = myClass::createObject();

   return 0;
}
Last edited on Sep 14, 2012 at 4:28pm
Sep 14, 2012 at 4:24pm
Try making the return value for createObject bool, that way you can return false if the input was empty.

Make the createObject take a references or a pointers to Foo and Bar - that way you can set their values in the function and not have to return them.

returning some thing for a void function as you have it now is an error, and you can only return one variable.

Edit:

Also don't have any public variables in a class, make them private or protected and provide functions to access them.

HTH
Last edited on Sep 14, 2012 at 4:26pm
Sep 14, 2012 at 4:42pm
Ensuring that the invariant for an object is established should ideally be done in a constructor. (Creating an object with data entered by the user is only one of many different possible ways for crating an object).

The classical way for the constructor to report an error is by throwing an exception. With that, any user of the class can create objects in a way that is most appropriate for that user's particular use case, without violating its encapsulation.

Something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct A
{
    A( const std::string& s ) : str(s)
    {
        if( str.empty() || !std::isdigit(str[0]) )
            throw std::domain_error( "the string does not start with a digit" ) ;
    }

    // ...

    private:
       std::string str ; // invariant: str is not empty and must start with a digit
};

And then:
1
2
3
4
5
6
7
8
9
10
11
A make_a_from_user_input()
{
    std::string s ;
    std::getline( std::cin, s ) ;

    try { return A(s) ; }
    catch( const std::exception& e )
    { std::cerr << "error in input: " << e.what() << ". try again\n" ; }

    return make_a_from_user_input() ;
}
Topic archived. No new replies allowed.