Home > other >  Can I create multiple constructors with the same arguments
Can I create multiple constructors with the same arguments

Time:09-17

Im new to C and I am curious to know if you can create multiple constructors with the same arguments. Say for example I have this class in which I have patients and I have their name and their age. I know I can create a constructor like this:

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

but could I create another constructor just like I did above. Something like:

hospital patientBilly(){
  setname("Billy");
  setage(32);
}

CodePudding user response:

The problem is that you redefine the constructor. Allowed is only one definition. Simplified example:

void myFunc (){};

void myFunc (){};

int
main ()
{
  myFunc ();
}

I whould make the Hospital class like this:

#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
}

CodePudding user response:

I believe you are currently only a bit confused. So lets become the things sorted...

A class describes how objects should behave. The constructor is part of that description and equal to all the instances it will later on create. Your first step for understanding should be: There is a single class and multiple instances/objects of it.

So you write a single class and give for each of the instances/objects different parameters to get different objects.

Example:

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();
}

You can also create a different class for every of your later created objects, but I believe that is never what you want to do, especially not at the beginning of your C career!

If you want to create some kind of list of instances, you can store the objects in containers and act on the containers as you like.

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

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

    for ( const auto& hos: objs )
    {   
        hos.Print();
    }   
}

CodePudding user response:

If I have understood correctly then what you need is to define two constructors

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

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

Then you will can write declaring an object of the class

hospital patientBilly( "Billy", 32 );

CodePudding user response:

In your problem you have two concepts, which you are trying to mix. hospitals and patients. So it makes sense to model them as two distinct classes.

This way you can model a patient as something that has an age and a name. And a hospital as something that "contains" patients.

Give the patient a contructor where you can pass age and name. And give the hospital a method or methods to add patients. In the example I show to variants of how you could add patients to a hospital.

I also have use unsigned variable types for numbers that can never be smaller then 0. And I use the const keyword a lot for places in the code where values must only be used, and should not be changed.

#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;
    }
}
  • Related