Я новичок в C ++, и мне любопытно узнать, можно ли создать несколько конструкторов с одинаковыми аргументами. Скажем, например, у меня есть этот класс, в котором у меня есть пациенты, и у меня есть их имя и возраст. Я знаю, что могу создать такой конструктор:

class hospital {
  hospital(){
    setname("John");
    setage(24);
  }
private:
  string name;
  int age;
};

Но могу ли я создать другой конструктор, как я сделал выше. Что-то вроде:

hospital patientBilly(){
  setname("Billy");
  setage(32);
}
-4
Conner Smith 10 Сен 2021 в 10:05

4 ответа

Лучший ответ

В вашей проблеме есть две концепции, которые вы пытаетесь смешать. больницы и пациенты. Поэтому имеет смысл моделировать их как два разных класса.

Таким образом, вы можете смоделировать пациента как человека, у которого есть возраст и имя. А больница как то, что «содержит» пациентов.

Дайте пациенту конструктор, в котором укажите возраст и имя. И дайте больнице метод или методы для добавления пациентов. В этом примере я показываю варианты того, как вы можете добавлять пациентов в больницу.

Я также использую беззнаковые типы переменных для чисел, которые никогда не могут быть меньше 0. И я часто использую ключевое слово const для тех мест в коде, где значения должны использоваться только и не должны изменяться.

#include <iostream>
#include <string>
#include <utility>
#include <vector>


//---------------------------------------------------------------------------------------------------------------------

class patient_t
{
public:

    // You need a constructor like this
    patient_t(const unsigned int age, const std::string& name ) :
        m_age{ age },
        m_name{ name }
    {
    }

    // getter function for observing private data
    const unsigned int& age() const noexcept
    {
        return m_age;
    }

    // getter function for observing private data
    const std::string& name() const noexcept
    {
        return m_name;
    }

private:
    unsigned int m_age;
    std::string m_name;
};

// a useful output function to have (will make code later shorter)
std::ostream& operator<<(std::ostream& os, const patient_t& patient)
{
    os << "Patient : " << patient.name() << ", age : " << patient.age() << std::endl;
    return os;
}

//---------------------------------------------------------------------------------------------------------------------

class hospital_t
{
public:
    void add_patient(const unsigned int age, const std::string& name)
    {
        m_patients.emplace_back(age,name); // will call patient constructor with two parameters age and name and puts it into vector
    }

    void add_patient(const patient_t& patient)
    {
        m_patients.push_back(patient); // store a copy of patient in the vector
    }

    const auto& patients() const
    {
        return m_patients;
    }

private:
    std::vector<patient_t> m_patients;
};

//---------------------------------------------------------------------------------------------------------------------

int main()
{
    hospital_t hospital;
    patient_t  billy{ 42, "Billy" };
    hospital.add_patient(billy);
    hospital.add_patient(31, "Jane");

    for (const auto& patient : hospital.patients())
    {
        std::cout << patient;
    }
}
0
P Kramer 10 Сен 2021 в 08:22

Проблема в том, что вы переопределяете конструктор. Допускается только одно определение. Упрощенный пример:

void myFunc (){};

void myFunc (){};

int
main ()
{
  myFunc ();
}

Я бы сделал класс больницы таким:

#include <string>
struct Hospital // struct here to signal we have no invariant. you could also use a class and make the member public
{
  std::string name{}; // no setter and getter if you do not have invariant.
  int age{};
};

int
main ()
{
  auto hospital = Hospital{ .name = "John", .age = 42 }; //c++20 Designated Initializers so we can construct Hospital with a name and age without defining a constructor
}
1
Koronis Neilos 10 Сен 2021 в 07:25

Я считаю, что в настоящее время вы только немного запутались. Итак, давайте разберемся ...

Класс описывает, как должны вести себя объекты. Конструктор является частью этого описания и равен всем экземплярам, ​​которые он создаст позже. Ваш первый шаг к пониманию должен быть следующим: существует один класс и несколько его экземпляров / объектов.

Итак, вы пишете один класс и даете каждому из экземпляров / объектов разные параметры для получения разных объектов.

Примере:

class hospital {
    public:
    hospital(const std::string& name_, int age_ ):
        name { name_ }, age{ age_ }{
        }

    void Print() const
    {   
        std::cout << "Hospital" << name << ":" << age << std::endl;
    }   

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

int main()
{
    hospital hospital1{ "John", 24 };
    hospital hospital2{ "Bill", 77 };

    hospital1.Print();
    hospital2.Print();
}

Вы также можете создать отдельный класс для каждого из ваших позже созданных объектов, но я считаю, что вы никогда не захотите этого делать, особенно в начале вашей карьеры на C ++!

Если вы хотите создать какой-то список экземпляров, вы можете хранить объекты в контейнерах и действовать с контейнерами по своему усмотрению.

int main()
{
    std::vector< hospital > objs;

    objs.emplace_back( "John", 24 );
    objs.emplace_back( "Bill", 77 );

    for ( const auto& hos: objs )
    {   
        hos.Print();
    }   
}
1
Jarod42 10 Сен 2021 в 07:41

Если я правильно понял, вам нужно определить два конструктора

hospital( const std::string &name, int age )
{
    setname( name );
    setage( age );
}

hospital() : hospital( "John", 24 )
{
}

Затем вы можете написать объявление объекта класса

hospital patientBilly( "Billy", 32 );
0
Vlad from Moscow 10 Сен 2021 в 07:24