I hate using pointers, but what else can I use?

I designed a class, in which, I have a member function will need to use other same class type object's member, so I thought of using pointers. But I really hate using pointers.

I wrote the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class iHate {
public:
    int value;
    std::vector<iHate *> Neighbor;
//...
    void foo() {}//In this function I will need use Neighbor->value
}

int main() {
    std::vector<iHate> IH(mySize);
    
    for(size_t i=0; i!=IH.size(); ++i) {
        //doing foo() stuff, calculating using neighbors' value in IH vector
    }
}


I am afraid if I expand the Neighbor of any object in IH or doing anything else alike, I will change all address and make the pointer pointing to nowhere...

Is there a better way? Thanks!
Last edited on
Hi,

Have a go at const references:

std::vector<const iLike &> Neighbor;

Hope all goes well.

Edit:

This is probably a bit nit-picky, but here goes anyway :

Btw, the idiom for a for loop is:

for(size_t i=0; i < IH.size(); ++i) {

This will always work, whereas the above doesn't if the increment is changed to some other value.
Last edited on
Thanks, TheIdeasMan!

const references need to be initialized when iLike is created, right? If that is the case, may not suit my problem, I won't know who will be its Neighbor when they are just created.
Have a go at const references:
std::vector<const iLike &> Neighbor;
You cannot have a vector of references. And references are subjects of dangling problem too if the original was deleted/deallocated.

You can use stor some kind of proxy to actual object inisde your vector in main to circumvent reallocation problem. Like cross between reference_wrapper and shared_ptr.
Hi,

It doesn't become a reference until it is pushed into the vector, so as long all is OK at that point.

Maybe an ordinary reference instead of a const one - still better than a raw pointer?

Better yet use a smart pointer, like std::unique_ptr, then you have RAII.

With regard to my edit in the last post, you could also consider using a ranged based for loop. Not sure if you already knew this - just putting it out there in case you didn't :+)

Cheers
I believe you can't have a vector of references. References are bound at construction time so I have no idea how you'd implement vector<Foo &).

I don't think unique_ptr is appropriate either since the Neighbor vector doesn't own the class instances it points to.

Just use a pointer. It's appropriate for this case.
Thanks !

ThingsLearnt += 2;

Sorry @northfly for giving bad info.
vector of weak_ptr? you can also check if the original pointer (must be stored in a shared_ptr now) has been deleted.
eg
1
2
3
4
5
6
7
8
9
10
std::vector<std::weak_ptr<int>> not_owned;
std::shared_ptr<int> owned(std::make_shared<int>(42));
not_owned.push_back(owned);

std::cout << *(not_owned[0].lock()) << std::endl; //prints 42
owned = std::shared_ptr<int>(); // frees the pointer
std::cout << "Pointer is " << (not_owned[0].lock()?"owned":"not owned") << std::endl;
// prints "not owned"
// trying to print the value accesses a nullptr
// std::cout << *(not_owned[0].lock()) << std::endl; 
Last edited on
If you intent to use std::vector to store all the nodes, you may store the index of the neighbours.

Then to access, you've got three possibilities:
(1) make the vector of nodes "global"
(a) take a reference to the vector in foo()
(\alpha) store a pointer to the vector

Alternative (1) is not so bad at it appears.
1
2
3
4
5
6
7
class graph{
   class node{
      //...
   };

   std::vector<node> all_the_nodes_in_the_graph;
};



> I am afraid if I expand the Neighbor of any object in IH (...)
> I will change all address and make the pointer pointing to nowhere...
you may touch the nodes as much as you want, their address (or the ones stored in the neighbour vector) will not change
the problem is if you touch the vector of the nodes, like inserting elements.
I hate pointers too:
http://www.lb-stuff.com/pointers
Topic archived. No new replies allowed.