3

I'm having a problem understanding vectors of pointers to class objects, I tried a test code to try and understand it but whenever I enter a name and try to output it, it prints out numbers instead of the actual name that I entered. I'm hoping someone can explain this to me as I'm new to these concepts.

Also Pets[0]->print(); dosent print at all while:

cout << "in main: " << Pets[0] << endl; 

prints.

class Pet
{ 
public:
    string name;
    Pet(const string&);

    string getName() const
    {
        return name;
    }
    void setName(const string& Name)
    {
        name = Name;
    }
    void print()const;
}

int main()
{
    vector<Pet*> Pets;
    string names;
    int done = NULL;
    do
    {
        {
            cout << "Name: ";
            cin >> names;
            Pets.push_back(new Pet(names));
            cin.ignore();
        }
        cout << "Add another ?" << endl;
        cin >> done;
    } while (done != 0);

    Pets[0]->print();
    cout << "in main: " << Pets[0] << endl;
    system("pause");
}
Pet::Pet(const string& Name)
{
}
void Pet::print()const
{
    cout << "Name: " << name;
}
L. F.
  • 19,445
  • 8
  • 48
  • 82
Luminate
  • 33
  • 2
  • 2
    @Yksisarvinen `std::string` has a default constructor which creates an empty string, so this is not UB. – aschepler Jun 07 '19 at 19:52
  • `Pets[0]->print();` does print, but it prints an empty string. You're forgetting to initialise the `name` member in your class constructor so it gets default-initialised to an empty string. – TrebledJ Jun 07 '19 at 19:55
  • @aschepler You're right, my bad. – Yksisarvinen Jun 07 '19 at 19:57
  • 2
    note that usually you would use a `std::vector`, ie no pointers, and rely on the vector to mangage the memory for you. In your code you have a memory leak, because everything `new`ed should also be `delete`d – 463035818_is_not_an_ai Jun 07 '19 at 20:04

1 Answers1

2

The constructor of Pet does not assign the parameter, hence it remains empty.

Write...

Pet::Pet(const string& Name) : name(Name) { }

to do this initialization.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • would ``` Pet::Pet(const string& Name) { name = Name; } ``` be the same ? why should i use the : part ? and sorry im very new and self learning – Luminate Jun 07 '19 at 19:58
  • @Luminate see here: https://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list – 463035818_is_not_an_ai Jun 07 '19 at 20:00
  • In this case it would practically be the same; the `:`-notation is initialization, whereas the `name = Name` in the body is assignment. Some things, like for example initializing a member of type `const` are allowed only through initialization but not through assignment. But - as mentioned - in your case it does not make too much difference. – Stephan Lechner Jun 07 '19 at 20:01
  • @Luminate You either have to put `{ this->name = Name; }` in the body of the constructor or put `: name(Name)` in the member init list. Up to you. – Wyck Jun 07 '19 at 20:03
  • 1
    Thank you very much, it fixed it. Simple thing and i looked for an hour for an answer when i could had asked here in minutes. – Luminate Jun 07 '19 at 20:05
  • @Luminate time to learn how to use a debugger. It lets you step through your code line by line and observe the values of the variables – 463035818_is_not_an_ai Jun 07 '19 at 20:06
  • @Wyck no need for `this`. C++ variable names are case sensitive ;) – scohe001 Jun 07 '19 at 20:06
  • @Wyck in the initializer list you can even do `Pet(string name) : name(name) {}`. no need to introduce a new name (pun intended), though its a tiny bit controversial – 463035818_is_not_an_ai Jun 07 '19 at 20:09