Smart Pointers in Vector

In this code:

Person.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Person.h
// A class defining people by their names
#pragma once
#include <cstring>
#include <iostream>
using std::cout;
using std::endl;
        
class Person
{
  public:
  // Constructor, includes no-arg constructor
  Person(const char* first = "John", const char* second = "Doe")
  {
    initName(first, second);
  }
        
  // Copy constructor
  Person(const Person& p)
  {
    initName(p.firstname, p.secondname);
  }
        
  // Move constructor
  Person(Person&& p)
  {
  firstname = p.firstname;
  secondname = p.secondname;

    // Reset rvalue object  pointers to prevent deletion
    p.firstname = nullptr;
    p.secondname = nullptr;
  }
        
  // Destructor
  ~Person()
  {
    delete[] firstname;
    delete[] secondname;
  }
        
  // Assignment operator
  Person& operator=(const Person& p)
  {
    // Deal with p = p assignment situation
    if(&p != this)
    {        
      delete[] firstname;
      delete[] secondname;
      initName(p.firstname, p.secondname);
    }
    return *this;
  }
        
  // Move assignment operator
  Person& operator=(Person&& p)
  {
    // Deal with p = p assignment situation
    if(&p != this)
    {
      // Release current memory        
      delete[] firstname;
      delete[] secondname;
      firstname = p.firstname;
      secondname = p.secondname;
      p.firstname = nullptr;
      p.secondname = nullptr;
    }
    return *this;
  }

  // Less-than operator
  bool operator<(const Person& p)
  {
    int result(strcmp(secondname, p.secondname));
    return (result < 0 || result ==  0 && strcmp(firstname, p.firstname) < 0);
  }
        
  // Output a person
  void showPerson() const
  {
    cout << firstname << " " << secondname << endl;
  }
        
  private:
  char* firstname;
  char* secondname;
        
  // Private helper function to avoid code duplication
  void initName(const char* first, const char* second)
  {
    size_t length(strlen(first)+1);
    firstname = new char[length];
    strcpy_s(firstname, length, first);
    length = strlen(second)+1;
    secondname = new char[length];
    strcpy_s(secondname, length, second);
  }
};



Main:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Ex10_03.cpp
// Storing pointers to objects in a vector

#include <iostream>
#include <vector>
#include <memory>
#include "Person.h" 

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::shared_ptr;
using std::unique_ptr;
using std::make_shared;

int main()
{
   vector<unique_ptr<Person>> people;               // Vector of Person object pointers
  const size_t maxlength(50);
  char firstname[maxlength];
  char secondname[maxlength];
  while(true)
  {
    cout << "Enter a first name or press Enter to end: ";
    cin.getline(firstname, maxlength, '\n'); 
    if(strlen(firstname) == 0)
      break;
    cout << "Enter the second name: ";
    cin.getline(secondname, maxlength, '\n'); 
    auto pPerson = unique_ptr<Person>(new Person(firstname, secondname));
    people.push_back(std::move(pPerson));
    //people.push_back(unique_ptr<Person>(new Person(firstname, secondname)));
    pPerson->showPerson();
  }

  // Output the contents of the vector
  cout << endl;
  for(auto& p : people)
    p->showPerson();

  cout << endl << " and again..." << endl;
  for(auto& p : people)
    p->showPerson();
  // Pointers in the people vector are now invalid
  // so remove the contents
  people.clear();

  return 0;
}


On line 45 and 46 it says the pointers are now invalid so remove the contents?

How are they invalid? Also when you call people.clear, the smart pointers also delete the person objects right?
closed account (zb0S216C)
Based on what I'm seeing, I think the author of the code meant that from the call to people.clear( )" and onwards, all elements of "people" are to become invalid.

Anmol444 wrote:
"Also when you call people.clear, the smart pointers also delete the person objects right?"

Yes. The last time I checked, safe-pointers free the memory they own within their own destructor, so when "people.clear( )" is called, each destructor of each safe-pointer is called, thereby freeing the memory held by each safe-pointer; thus, invalidating each element of "people".

Wazzak
Last edited on
Alright thanks!

Although it isn't very clear, I guess I will just go with that.
@Anmol444

Just a really minor thing - why can't you use std::string instead of char arrays?

std::string has a lot of good stuff in it - like the == operator - use instead of strcmp, for example. And you have access to all the algorithms as well.

HTH
He said lets just "pretend" we forgot strings and dynamically store cstrings.

I know but my author just wanted to use cstrings.
He also stated to always use std::string in any production program.
Topic archived. No new replies allowed.