Can you delete a pointer from a vector with a given pointer?

I need to remove an object pointer from a vector with only the target object pointer. Example:

1
2
3
4
5
6
7
8
std::vector<GameObject*> objects;

void Game::DestoryObject(GameObject* object)
{
	//remove object from vector
	//delete object
}


Is there a way to do this without looping through the whole vector?
Last edited on
kong288 wrote:
Is there a way to do this without looping through the whole vector?
No.

You should not be using pointers (http://www.LB-Stuff.com/pointers ) - instead, use std::unique_ptr inside your vector:

std::vector<std::unique_ptr<GameObject>> objects;

Due to your design you still have to loop through the vector with linear search.
Last edited on
Can I point out that new can still be used with RAII, it's delete that isn't needed and that you shouldn't necessarily replace all pointers with unique_ptr and shared_ptr, only those to dynamically allocated memory. This isn't necessarily to do with this situation, but is to do with the link you posted.
is there a better design to delete something like this besides looping through every object?
You could store the objects in a set since the order is unimportant to you. The comparison function can be based on the memory address and you can let the set optimize removal for you.

@shadowmouse: I don't use pointers except in extremely rare cases.
Last edited on
I can confirm you don't really need raw pointers since C++11.
On the topic: either you or the stl is going to loop through the vector to find this item. You may use vector::find or std::find, but it will not outperform your own loop (neither will your loop outperform the stl).
shadowmouse > you shouldn't necessarily replace all pointers with unique_ptr and shared_ptr, only those to dynamically allocated memory.

S G H >> I can confirm you don't really need raw pointers since C++11

shadowmouse, +1
Standard library smart pointers can be used in conjunction with custom deleters; so they can handle some RAII scenarios where dynamically allocated memory is not involved. For instance:
1
2
3
4
5
6
7
8
9
10
11
#include <memory>
#include <windows.h>

void foo()
{
    std::unique_ptr< void, decltype( &CloseHandle ) > temp( CreateWaitableTimer(0,0,0), &CloseHandle ) ;
    HANDLE htimer = temp.get() ;
    
    // use timer
    // ... (may throw)
}


The smart pointers provided by the standard library are not designed to be replacements for all pointers; they are there to provide library support for automated resource management.

Pointers provide an indirect way to refer to an object, which may or may not exist (just as references and reference wrappers provide an indirect way to refer to an object which must exist)

For instance: int std::stoi( const std::string& str, std::size_t* pos = nullpr, int base = 10 );
The object referred to by str must exist; so a reference is appropriate.
The object pointed to by pos may or may not exist; there is no ownership issue involved; and a raw pointer is appropriate.

Raw non-owning pointers continue to be central to C++; C++11 hasn't really changed anything with respect to that. Smart pointers were widely in use in production C++ code, even before C++ was standardised in 1998. C++11 merely added library support for the most common smart pointer usage scenarios.

This is what I tend to follow:
a. reference: a non-reseatable non-owning 'direct reference' to an object which must exist.
b. reference wrapper: a reseatable non-owning 'direct reference' to an object which must exist.
c. pointer: a reseatable non-owning 'direct reference' to an object which may or may not exist.
d. smart pointer: if and only if none of a, b, or c apply. C++11 smart pointers for 'direct reference' with 'deleter' semantics; custom smart pointers for 'indirect reference' semantics.
Yes, but move semantics weren't a thing in C++03, which means no unique_ptr.
For that example, std::optional, or your own class will fit.
Anyways, you certainly won't store the size_t* as a pointer itself- you're 99% going to get the address as soon as your code reaches the function call, which means, you're still not having to worry about pointer de/allocations and potential exception caveats.
> Yes, but move semantics weren't a thing in C++03, which means no unique_ptr.

Which means nothing more than that legacy C++ did not support move semantics. It does nothing to validate the gross and utterly simplistic proposition: 'you don't really need raw pointers since C++11'.


> For that example, std::optional

Please try to understand the difference between value semantics and reference semantics.
std::experimental::optional<T> holds an optional (non-polymorphic) value of type T.

A program that necessitates the instantiation of template optional for an lvalue reference or rvalue reference type ... is ill-formed.

The grotesque std::experimental::optional< std::reference_wrapper<T> > over the straightforward T*, anyone?


> you're still not having to worry about pointer de/allocations and potential exception caveats.

Precisely.
I'm glad that we have progressed quite some distance from 'you don't really need raw pointers since C++11'.
Even without having to start answering uncomfortable questions like: 'how does one implement a smart pointer?'
@move semantics: no move semantics = no make_unique = you still need to use "new".
This said, if you understand pointers, it's way easier to require optional parameters... for people who doesn't, well they aren't in a worst position, since for every use case the stl has an alternative.
I avoid raw pointers because they have so many different uses. Even if it is simpler to write code with a raw pointer, I always consider the readability first. Even so, the places where it would be easier to write a raw pointer are far and few between for me. I guess it depends on what you use C++ for.
Last edited on
As long as one is not under the delusion that std::experimental::optional<T> subsumes the functionality of T*, things would be fine.

'The World’s Dumbest Smart Pointer' has finally made it into the Library Fundamentals 2 TS. std::experimental::observer_ptr<T> is a sane drop-in replacement "for near-trivial uses of bare/native/raw/builtin/dumb C++ pointers."

We have found that such a template provides us a standard vocabulary to denote non-owning pointers, with no need for further comment or other documentation to describe the near-vacuous semantics involved. As a small bonus, this template’s c’tors ensure that all instance variables are initialized.
Topic archived. No new replies allowed.