2

i dont really get the fields of the template std::vector, the first one specifies the type, for example a class, but i dont get the allocator, pointer and reference variables.

i will provide a simple example, i want to use a vector of class person, so i have to say to the template vector: hey, store me some person's, but i also have to tell the vector how to allocate that class. (1)How would a correct syntax be for that example?

some code to start with:

side note, in the person's constructor,c(2)should i use date*?

class date
{
public:
    int m_nMonth;
    int m_nDay; 
    int m_nYear;

    int getMonth(return m_nMonth;)
    int getDay(return m_nDay;)
    int getYear(return m_nYear;)

    void setDate(int month, int day, int year)
    {
            m_nMonth=month;
            m_nDay=day;
        m_nYear=year;
    }

    date()
    {
        setDate(0,0,0);
    }

    date(int month, int day, int year)
    {
        setDate(month,day,year);
    }

    void printDate()
    {
        printf("%d/%d/%d", m_nMonth, m_nDay, m_nYear);
    }
}

class person
{
public:
    int m_nID;
    char m_sName[128];
    char m_sSurname[128];
    date m_cBirthDay;

    void setName(const char* name)
    {
        strncpy(m_sName, name, 127);
        m_sName[127]= '\0';
    }

    void setSurname(const char* surname)
    {
        strncpy(m_sSurname, surname, 127);
        m_sName[127]= '\0';
    }

    void setBirthDay(date* bday);
    {
        m_cBirthDay.date(bday.getMonth(), bday.getDay(), bday.getYear)
    }

    person(int id, const char* name, const char* surname, date bday)/*should it be date* bday? why?*/
    {
        m_nID=id;
        setName(name);
        setSurname(surname);
        setBirthDay(bday);
    }

}

i suppose you have to declare a function inside class person, called allocator, that is whats passed as second argument when you call, (3)how would that allocator function be defined?:

vector <person*, /*some allocator call*/> ImAVector;

then, (4)how could i push something in the vector, (5)would this work?:

person* someperson;
someperson.person(/*arguments*/);
ImAVector.push_back(someperson);

(6)how could i retrieve the pointer to a particular instance? (7)can i use the iterator to do something like this?:

//(6)
person* = ImAVector[someIterator];
//and then (7)
ImAVector[someIterator].setName(someConstCharPointer);
string* something = person.getName();

also, (8)does the allocator have anything to do with the constructor? (9)its common procedure to fill your class's fields right after allocating the instance of the class? (10)can an allocator call a constructor?

And the last questions: (11)what is the reference field, the pointer field, and their const counterparts?

I know its a lot to write, but ive spent the last two days searching for examples without success, so it would be nice if someone shed some light into this rarely discussed topic, ive numerated all questions for an easy response.

I appreciate any answers :)

  • See e.g. [this answer](http://stackoverflow.com/a/8019003/841108) for an example of allocator. Most of the time you don't need any allocator. – Basile Starynkevitch Oct 31 '13 at 07:43
  • 1
    Why would you want a custom allocator? Just do e.g. `std::vector persons; persons.push_back(new person(...));` It'll work even without using pointers: `std::vector persons; persons.push_back(person(...));` – Some programmer dude Oct 31 '13 at 07:46
  • And you usually want to use some smart pointer in the vector, e.g. `std::vector>`. If possible use a C++11 compiler. – Basile Starynkevitch Oct 31 '13 at 07:48
  • thanks for the quick response, i dont get the part of the smart pointer, what would it be used for? – 1.auxl2.1laux.2 Oct 31 '13 at 07:54
  • Please take hours or days to read a good C++11 programming book. We don't have lot of time to teach all that to you. See also http://www.cplusplus.com/ & http://cppreference.com/ – Basile Starynkevitch Oct 31 '13 at 07:57
  • @1.auxl2.1laux.2: Smart pointers are used to make sure that dynamically created objects are correctly deleted; it's very hard to avoid memory leaks and other problems without them. Your C++ book should describe them in detail; otherwise, see (for example) http://stackoverflow.com/questions/106508. – Mike Seymour Oct 31 '13 at 08:00
  • Sorry, i know its a lot to ask for, ive tried searching for a free c++ book, but doesnt seem to be any, and in the country im living in i can't order books from other places, is there any free book with good examples instead of the confusingly short definitions of cppreference.com – 1.auxl2.1laux.2 Oct 31 '13 at 08:03
  • You could search the web for the "confusingly short definitions" (e.g. look on wikipedia, and the [C++ wikibook](http://en.wikibooks.org/wiki/C++_Programming) ...) – Basile Starynkevitch Oct 31 '13 at 08:19

2 Answers2

6

How would a correct syntax be for that example?

Unless you have a good reason for storing pointers, don't. Then you just declare

std::vector<person> people;

// In C++11, you can create people in place
people.emplace_back(id, name, surname, birthday);

// Historically, you had to create a person and copy it in
people.push_back(person(id, name, surname, birthday));

and all the allocation is managed for you.

Reasons for wanting pointers include:

  • the vector is not supposed to manage the objects. In that case, you don't need to tell the vector how to allocate them.
  • perhaps person is a base class and you want to store various different subtypes.

In that case, I don't think you can use an allocator to help; instead, you could store smart pointers to automatically delete the objects when the pointer is removed from the container:

std::vector<std::unique_ptr<person>> people;
people.push_back(std::unique_ptr<person>(new person(id, name, surname, birthday)));

The alternative is to juggle raw pointers and try to delete the objects at the right time; but life's too short for that nonsense.

(2)should i use date*?

No. For a large or complicated class, it might be beneficial to pass a const reference, const date&; but this class is simple enough to pass by value. Passing a pointer would be weird, except in languages like C where that's the only way to pass by reference.

how could i retrieve the pointer to a particular instance?

people[index] gives a reference (not pointer) to the person with that index. If you really want a pointer for some reason, use & to take the address:

person & ref = people[index];
person * ptr = &ref;

can i use the iterator to do something like this?

No, [] is used to access by the array index, not to dereference an iterator. If you have an iterator it, then *it gives you a reference to the object.

does the allocator have anything to do with the constructor?

No, allocators are used if you have special memory-management requirements, and don't want the vector to simply allocate memory on the heap. There use is quite rare.

its common procedure to fill your class's fields right after allocating the instance of the class

It's common to initialise all the data members in the constructor, yes.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • about (2), of course! its all much more clear that way, coming from c, c++ can be a little harsh, but this is a much better way – 1.auxl2.1laux.2 Oct 31 '13 at 08:08
2

You don't need to specify anything other than the type.

vector<person> people;
people.emplace_back(/* constructor arguments for a person */);  // constructs the person in place instead of copying into the vector.

person p;
p.stuff();
vector.push_back(p);  // copies p into the vector

etc. Basically the defaults for allocator and the other fields are good enough, no need to specify them unless you have reason to override the default behavior. I've never had reason to do so.

Charlie
  • 1,487
  • 10
  • 9