Don't allow empty object in vector

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
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
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
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.