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';
}