Home > database >  Pointing on vector elements
Pointing on vector elements

Time:07-13

I've got a vector of objects (apples) and I need a pointer to jump through every element, to print "size" value on every object in "apples". I tried vector::iterator, pointing whole vector but I still cannot get correct solution

#include <iostream>
#include <vector>

class Apple{
public:
    int size;
    Apple(int size): size(size){}
    void print(){
        std::cout<<size;
    }
};

    std::vector<Apple*>apples = {new Apple(21), new Apple(37), new Apple(66)}; 
    Apple* ptr = apples[0];

void nextApple(){
    ptr  ;
    ptr->print(); //returns 0
}

int main()
{
    nextApple();
    return 0;
}

Big thank You for any help!

CodePudding user response:

To iterate through any T[] array using a pointer, you need to use a T* pointer, and you need to point it initially at the address of the 1st element, not the value of the element.

Your vector's element type is T = Apple*, not T = Apple, so you need to use an Apple** pointer rather than an Apple* pointer, eg:

#include <iostream>
#include <vector>

class Apple{
public:
    int size;
    Apple(int size) : size(size){}
    void print(){
        std::cout << size << std::endl;
    }
};

std::vector<Apple*> apples = {new Apple(21), new Apple(37), new Apple(66)}; 
Apple** ptr = &apples[0];

void nextApple(){
      ptr;
    (*ptr)->print();
}

int main()
{
    nextApple();
    return 0;
}

Using an iterator instead (or even an index) would have worked just fine, eg:

#include <iostream>
#include <vector>

class Apple{
public:
    int size;
    Apple(int size): size(size){}
    void print(){
        std::cout << size << std::endl;
    }
};

std::vector<Apple*> apples = {new Apple(21), new Apple(37), new Apple(66)}; 
std::vector<Apple*>::iterator iter = apples.begin();
// or: size_t index = 0;

void nextApple(){
      iter;
    (*iter)->print();

    // or:
    //   index;
    // apples[index]->print();
}

int main()
{
    nextApple();
    return 0;
}

That being said, using a vector of raw Apple* pointers is not a good idea. You have to delete the Apple objects when you are done using them. At the very least, you should wrap the pointers in std::unique_ptr to avoid memory leaks, eg:

#include <iostream>
#include <vector>
#include <memory>

class Apple{
public:
    int size;
    Apple(int size): size(size){}
    void print(){
        std::cout << size << std::endl;
    }
};

std::vector<std::unique_ptr<Apple>> apples = {std::make_unique<Apple>(21), std::make_unique<Apple>(37), std::make_unique<Apple>(66)}; 
auto *ptr = &apples[0];
// or: auto iter = apples.begin();
// or: size_t index = 0;

void nextApple(){
      ptr;
    (*ptr)->print();

    // or:
    //   iter;
    // (*iter)->print();

    // or:
    //   index;
    // apples[index]->print();
}

int main()
{
    nextApple();
    return 0;
}

But really, just get rid of the dynamic allocation altogther, you don't need it in this example:

#include <iostream>
#include <vector>

class Apple{
public:
    int size;
    Apple(int size): size(size){}
    void print(){
        std::cout << size << std::endl;
    }
};

std::vector<Apple> apples = {21, 37, 66}; 
Apple* ptr = &apples[0];
// or: auto iter = apples.begin();
// or: size_t index = 0;

void nextApple(){
      ptr;
    ptr->print();

    // or:
    //   iter;
    // iter->print();

    // or:
    //   index;
    // apples[index].print();
}

int main()
{
    nextApple();
    return 0;
}

CodePudding user response:

The code in the question is not idiomatic C ; more like a Java design. In C iterators just work:

void show_apples() {
    std::vector<Apple> apples =
        { Apple(21), Apple(37), Apple(66) };
    for (auto iter = apples.begin(); iter != Apples.end();   iter)
        std::cout << iter->size << ' ';
    std::cout << '\n';
}
  • Related