简体   繁体   中英

Condition in class constructor c++

I have to write a definition of class containg personal data (such as name, surname and age) with a condition that age cannot be less than 1. I was trying to catch an exeption in the class constuctor:

class Person {

public:
    Person (std::string name, std::string surname, int age) {
        try{
            this -> name = name;
            this -> surname = surname;
            this -> age = age;

            if(age < 1)
                throw std::string("Error! Age cannot be less than 1!");
       }

       catch(std::string ex){
           cout << ex << endl;
       }
};

private:
    std::string name;
    std::string surname;
    int age;
};

And that works fine but the most important thing is that the object with age < 1 shouldn't be created at all while with this solution I only get an error and object as person1("Thomas", "Something", -5) is still being created.

What is the best way to "block" the creation of objects which do not fulfil the condition?

One way to guarantee you don't create an object with bad values is to throw an exception in the constructor, like you do. Only don't catch it, let it be caught by the code that is trying to create a bad object:

class Person
{
public:
    Person(std::string name, std::string surname, int age) {

        if(age < 1)
            throw std::string("Error! Age cannot be less than 1!");

        this->name = name;
        this->surname = surname;
        this->age = age;

    }

private:
    std::string name;
    std::string surname;
    int age;
};

As an aside, it is more usual to use the constructor's initialization list to initialize variables:

class Person
{
public:
    Person(std::string const& name, std::string const& surname, int age)
    : name(name), surname(surname), age(age) {

        if(age < 1)
            throw std::runtime_error("Error! Age cannot be less than 1!");
    }

private:
    std::string name;
    std::string surname;
    int age;
};

By throwing in the constructor you can guarantee that the object is valid when you use it:

int main()
{    
    try
    {
        Person p("John", "Doe", -5);

        // if we get here the person must be valid
    }
    catch(std::exception const& e)
    {
        std::cerr << e.what() << '\n';
        return EXIT_FAILURE;
    }
}

Also note I throw a std::exception derived object rather than a std::string as that is more idiomatic and recommended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM