简体   繁体   English

类构造函数C ++中的条件

[英]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: 我必须写一个包含个人数据(例如姓名,姓氏和年龄)的类的定义,条件是年龄不能小于1。我试图在类构造器中抓住一个例外:

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. 效果很好,但最重要的是, 根本不应该创建年龄小于1的对象,而使用此解决方案我只会遇到一个错误,因为person1(“ Thomas”,“ Something”,-5)是仍在创建中。

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. 另请注意,我抛出了std :: exception派生对象,而不是std::string因为这更惯用和推荐。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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