Damian Piotrowski
Damian Piotrowski

Reputation: 13

Access array in main by pointers by method in class

I need some help with my code, i prepare for my coming exam.

I have code with 3 classes: Package, Person and Courier(inherit from Person). Then i have array in main with Packages. And now i'm stuck at some point where i have 'Courier k1(p, p+3);' which means i need to assign to this Courier packages from p to p+3 by pointers. And my problem is that i don't know how to access this all packages i need by method from any class. Simple example of code:

class Package
{
 string _address;
 float _value;
};

class Person
{
 string _name, _lastname;
};

class Courier:public Person
{
vector < Package > tab;
}

int main()
{
  Package p[] = {
    Package("Dabrowskiego 33", 123.00),
    Package("NMP 12", 40.00),
    Package("Armii Krakowej 4", 30.00),
    Package("Andersa 6", 51.00),
    Package("Kukuczki 13", 12.00),
    Package("Skrzyneckiego 5", 40.00),
  };
   Courier k1(p, p+3);
   cout << k1.value() << endl;

return 0;
};

Code above is only example, code in main is unchangeable because it's base from teacher. I tried to make method in Courier with count amount of packages, and then add values to vector like this

for(int i=0;i<amount;i++)
            {
                tab.push_back(Package(*(p+i)));
            }

I dont know if it's a good way, even possible to do, but then i don't know how to display values by value() function.

Regards

Edit://

Thanks for help everyone, i managed to end my program and everything seems to work. But i have one doubt.

Courier k2;
  cout << "---- 8 ----" << endl;
  cout << k2.value() << endl;

  {
    Courier k3(k1);
    cout << "---- 9 ----" << endl;
    cout << k3.value() << endl;

    k2 = k3;
    cout << "---- 10 ----" << endl;
    cout << k2.value() << endl;

    k1 = k1 + p[4];
    k1 = k1 + p[5];

    cout << "---- 11 ----" << endl;
    cout << k1.value() << endl;

  }

  cout << "---- 12 ----" << endl;
  cout << k2.value() << endl;

Now i'm concerned. Right now values look like this:

  1. 8 - returns 0(as my default constructor set value to 0 if there is no value)
  2. 9 - returns 193 as it sums all values
  3. 10 - return same as above cuz it assign it from k3
  4. 11 - returns 245 because it add 2 values
  5. 12 - returns 193.

And now, should it work like this or values 8 and 12 should be the same (equal 0) and only values inside brackets should change?

Upvotes: 0

Views: 65

Answers (2)

aschepler
aschepler

Reputation: 72356

First, the line Courier k1(p, p+3); implies that class Courier has a constructor which accepts two pointer arguments. That would look like:

class Courier : public Person
{
public:
    Courier(const Package* first, const Package* last);
private:
    std::vector<Package> tab;
};

(If your class hasn't discussed const much yet, you can probably safely leave it out for this exercise, since main doesn't use it.)

Defining a constructor involves initializing all the base classes and members. In this case, the base class Person and the member tab.

The code isn't saying anything about a first name or last name, so default-constructing the Person base subobject makes sense.

Luckily, std::vector<T> already has a constructor which takes a pair of pointers representing a range. It's #5 on cppreference, the one that looks like

template< class InputIt >
vector( InputIt first, InputIt last,
        const Allocator& alloc = Allocator() );

since a raw pointer is a type of Input Iterator.

So the constructor definition (as it appears if written outside the class definition):

Courier::Courier(const Package* begin, const Package* end)
    : Person(),        /* or just omit the Person() */
      tab(first, last) /* copies all the Packages into the vector */
{}                     /* nothing else to do after tab is initialized */

Upvotes: 2

user4581301
user4581301

Reputation: 33932

If you have a pointer to an object, you can do with it whatever the object will allow. What I think you want something like

Courier (Package * current, Package * end)
{
    while (current != end) // loop until the end. Note this could be off by one.
                           // I don't know id the last Package is supposed to be added
    {
        tab.push_back(*current); // copy current Package into vector
        current++; //advance to next Package
    }
}

Why

You don't have an amount, just a start and end, so you start at the start and look at all of the Packages up to the end (possibly including the end package, but this would be unusual). It looks like your instructor may be trying to teach iterators.

Note:

Konrad points out below that this can be reduced to constructing the vector more intelligently:

Courier (Package * start, Package * end):tab(start, end)
{
}

This is the smarter way to fill the vector, but it doesn't demonstrate how to iterate through the pointers so it's "less educational."

Upvotes: 1

Related Questions