How to test if a parent pointer has been allocated? - c++

I have a reset() function that goes through a bunch of data and resets it. One of these is a pointer to a custom class, let's say Apple *a;
The Apple class has a vector<Seed *> object, and a method resetSeeds() to go through and reset them all.
If reset() is called before a is allocated, I don't want resetSeeds to iterate over its Seed objects, since these aren't allocated yet. How do I do this?

Set a to NULL to begin with. Then, in reset(), only call a->resetSeeds() if a is not NULL:
class Foo
{
private:
Apple* a;
public:
Foo() : a(NULL) { }
void reset()
{
if (a != NULL) {
a->resetSeeds();
}
}
};
If you're using C++11, switch out NULL in favour of nullptr.

Initialize the pointer in the initialization list. That way it's set even before calling the constructor:
class Worm
{
Apple *a;
Worm() : a(0)
{
// a is 0
}
void setApple(Apple *_a)
{
a = _a;
}
void eat(void)
{
if(a)
a->chew();
}
}

Set a to NULL at its declaration, or in the relevant constructor if it's an instance field, and check for NULL before you use it.
I'd say it's good practice to keep any reachable invalid pointer NULL, and to check any pointer for NULL before you use it.

Related

C++ deleting a object from it's own class

I have the following situation.
FooClass* fooPointer = new FooClass();
int main() {
while (/*logic*/) {
if (fooPointer) {
// some logic
}
}
}
class FooClass {
void fooClass::fooMethod() {
if (/*logic*/) {
//logic
delete this;
}
}
}
So I am basically deleting the object. However on the next iteration It still enters the if statement in the main method (
if (fooPointer) {
// some logic
}
).
Why doesn't it recognize that the object has already been deleted with the null check?
Calling delete on an object usually is doing two things:
It calls the destructor
It frees the memory of the object
It does not set anything to null nor does it change the value of pointers in any other means. That's why your check doesn't work.
So if you want to go this way, you somehow have to null your pointer yourself.

How to delete an object without having access to it?

I know that whenever I create a new object for a class, that object is stored in memory. I also know that in creating that object, it can only be accessed within the set of braces it is created in (Scope visibility). I need to find a way to delete that object outside of the braces it is created in. I have looked at smart pointers briefly, and it might be what I want to use? I'm assuming it is, I just don't know for sure. If a smart pointer can satisfy my needs, would someone please provide me with an example of how to use a smart pointer to access an object outside of where it has been created? Thanks :)
EDIT:
Example of what I'm trying to do:
class ModernWarfare2
{
//my class
ModernWarfare2();
};
DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
switch(XamGetCurrentTitleId())//a function that tells what game is being played
{
case Xbox360Dashboard://if i were to exit the game mw2
{
if(CODAllocated)//a boolean
{
//free the memory of the previous cod game
if(MW2Allocated)//another boolean
{
delete[] MW2;//gives me an error because i dont have access to MW2
}
}
break;
}
case COD_MW2:
{
if(!CODAllocated)
{
if(!MW2Allocated)
{
ModernWarfare2 *MW2 = new ModernWarfare2();
}
}
break;
}
}
return XamInputGetState(r3,r4,r5);
}
How do I fix my issue?
I also know that in creating that object, the object can only be accessed within the set of braces it is created in.
Not necessarily; that's only true when you construct objects with automatic storage duration, like this:
void foo()
{
T obj;
}
Such objects, yes, go out of scope.
Objects you allocate dynamically do not:
void foo()
{
T* obj = new T();
}
This is a memory leak because you never destroy *obj; however, you can access it from pretty much wherever you like:
T* foo()
{
return new T();
}
void bar()
{
T* obj = foo();
// yay!
}
or:
T* obj = nullptr;
void foo()
{
obj = new T();
}
void bar()
{
// do stuff with *obj
}
void baz()
{
foo();
bar();
}
This all gets dangerous and messy because you end up with spaghetti code in which the lifetime of the dynamically-allocated object is unclear, and in the examples above I still haven't approached the topic of eventually destroying the object. You have to be really careful not to destroy it whilst you're still using it.
This is where smart pointers come in, but if you want a tutorial on using smart pointers I'm going to have to refer you back to your C++11 book.
"I also know that in creating that object, the object can only be accessed within the set of braces it is created in." - This depends on how you create the object.
Example 1 (can't be accessed outside braces):
void func(void)
{
Object obj("foo", "bar");
}
Example 2 (can be accessed outside braces):
Object* func(void)
{
Object* obj = new Object("foo", "bar");
return obj;
}
Example 2 can be deleted using the keyword delete.
Take a look here for more information on pointers.
I haven't personally found a use for smart pointers but MSDN has good information on the topic here
By creating MW2 with
{
ModernWarfare2 *MW2 = new ModernWarfare2();
}
I was not able to reference MW2 elsewhere. By doing this, I can create it and delete it in two different spots:
class ModernWarfare2
{
//my class
ModernWarfare2();
};
ModernWarfare2 *MW2 = NULL;
DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
switch(XamGetCurrentTitleId())//a function that tells what game is being played
{
case Xbox360Dashboard://if i were to exit the game mw2
{
if(CODAllocated)//a boolean
{
//free the memory of the previous cod game
if(MW2Allocated)//another boolean
{
delete MW2;//gives me an error because i dont have access to MW2
}
}
break;
}
case COD_MW2:
{
if(!CODAllocated)
{
if(!MW2Allocated)
{
if(MW2 == NULL)
{
MW2 = new ModernWarfare2();
}
}
}
break;
}
}
return XamInputGetState(r3,r4,r5);
}
I think what you need is basic design pattern
Make the data and the functions members of a class
class SomeHandler
{
public:
void Acquire( /* some source */ );
void DoSomething( /* eventual parameters */ );
bool TrySomething(); // returns true if successful
private:
void internalFunction();
bool inGoodState;
SomeType dataINeed;
SomeOtherType otherData;
};
void SomeHandler::Acquire( /**/ )
{
// implement like this
}
now the functions can access the all the data
the use it like
int main()
{
SomeHandler h;
h.Acquire();
if( h.TrySomething() )
{
h.DoSomething();
}
}
Based on your code snippet, You have to save your pointer MW2 for
future so that you can delete the pointer.
I would suggest you to change
if(!MW2Allocated)
to
if(!MW2)
so that you don't have to create another variable for saving the reference to your allocated memory
Offcourse you have to move
ModernWarfare2 *MW2
to a larger scope (move it to the scope same as MW2Allocated) and initialize it to NULL.
Use "nullptr" instead of "NULL" if you are using C++11 supported compiler.
Also makesure you use
delete
instead of
delete[]
since this is not an array allocation
I don't think you can use smart pointers to skip saving your reference to the allocated memory,
since they are meant to make the memory deletion automatic or to make sure two deletion doesn't occur
for the same memory.
Refer to
http://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers
for a good explanation about smart pointers

use iterator ptr to update vector of unique_ptr

Code as follows:
#include "MyObject.h"
#include <vector>
#include <memory>
class MyCollection {
private:
std::vector<std::unique_ptr<MyObject*>> collection;
public:
MyCollection();
virtual ~MyCollection();
int insert(MyObject* newValue);
};
int MyCollection::insert(MyObject* newValue) {
if (collection.empty()) {
collection.push_back(move(make_unique<MyObject*>(newValue)));
return 0;
}
int index = collection.size()-1;
collection.resize(collection.size()+1);
vector<unique_ptr<MyObject*>>::reverse_iterator pos = collection.rbegin();
for ( ; (index >= 0) && (pos+1) != collection.rend() && stringToUpper((*(pos+1)->get())->getObjectName()) > stringToUpper(newValue->getObjectName()); ++pos) {
pos = (pos+1);
index--;
}
pos = ?newValue; // How do I do this?
//pos->reset(move(make_unique<MyObject*>(newValue)));
return index+1;
}
make_unique() implementation taken from http://scrupulousabstractions.tumblr.com/post/37576903218/cpp11style-no-new-delete
My question is there a way to do what I'm attempting with the assignment to the reverse_iterator (pos = newValue)? One of my pitiful attempts is shown in the commented code.
Thanks!
Firstly, as others have pointed out, you want a vector<unique_ptr<MyObject>> not vector<unique_ptr<MyObject*>>. It is fine to have a unique_ptr containing an abstract class (make sure the base class has a virtual destructor). You can implicitly cast from a unique_ptr containing a derived class.
Ideally I think MyCollection::insert should take a unique_ptr not a raw pointer so that the calling code creates objects using make_unique in the first place but let's leave it like it is for now.
I think you have a bit of confusion with make_unique. make_unique is designed to create an object and wrap it in a unique_ptr in one go, safely. Your MyCollection::insert doesn't really need to use make_unique because the object is already created. unique_ptr has a constructor that takes a raw pointer so you can create one directly from the raw pointer.
You can then push the unique_ptr onto the collection or replace unique_ptrs in the collection with new unique_ptrs fine:
class MyObject {
public:
virtual ~MyObject() = 0
};
MyObject::~MyObject() {}
class SimSolverObject : public MyObject {
};
class MyCollection {
private:
std::vector<std::unique_ptr<MyObject>> collection;
public:
void insert(MyObject* newValue);
};
void MyCollection::insert(MyObject* newValue) {
//...
// if we want to add to the collection
collection.push_back(std::unique_ptr<MyObject>(newValue));
// if we want to replace at iterator pos in collection
*pos = std::unique_ptr<MyObject>(newValue);
}
// calling code
MyCollection mc;
MyObject* newValue = new SimSolverObject();
mc.insert(newValue)
If you do decide to change MyCollection::insert to take a unique_ptr it would look something like this:
void MyCollection::insert(std::unique_ptr<MyObject> newValue) {
//...
// if we want to add to the collection
collection.push_back(std::move(newValue));
// if we want to replace at pos
*pos = std::move(newValue);
}
Edit: Your for loop looks a bit suspicious. I am not quite sure what you are trying to do but are you sure you want to increment the iterator twice? Once in the body of the for and once in the loop expression? I suspect the iterator is skipping over your condition and going out of bounds of the vector. When it hits the index condition you may be left with an invalid iterator.

Initializing member data of pointer type to NULL in constructor that uses Builder Pattern

I have a constructor which uses an internal Builder object to instantiate a complex object. Five of the members in the data structure are of pointer types. However, using this pattern I am running into problems when the object is destroyed. The following is what my constructor looks like, with member initialization list:
Player::Player(const Builder& builder)
:m_name(builder._name)
,m_description(builder._description)
,m_primaryAttributes(builder._primaryAttributes)
,m_abilityAttributes(builder._abilityAttributes)
,m_armor(builder._armor)
,m_weapon(builder._weapon)
,m_inventory(new ComponentMap())
{}
The client code works well, as expected:
Player* player = Player::Builder()
.name("Dylan")
.description("Super bad-ass hero of the game")
.primaryAttributes(createPrimaryAttributes())
.abilityAttributes(createAbilityAttributes())
.weapon(createWeapon())
.armor(createArmor())
.build();
However, if I omit one of the arguments in the message chain, and then destroy my Player object, bad stuff happens:
Player* player = Player::Builder()
.name("Dylan")
.description("Super bad-ass hero of the game")
.primaryAttributes(createPrimaryAttributes())
.abilityAttributes(createAbilityAttributes())
.armor(createArmor())
.build();
// ...
delete player;
// ...
// cleanMemory() gets called in Player::~Player()
void Player::cleanMemory()
{
if(m_primaryAttributes != NULL )
delete m_primaryAttributes;
if(m_abilityAttributes != NULL )
delete m_abilityAttributes;
if(m_inventory != NULL )
delete m_inventory;
if(m_weapon != NULL) // oops, bad stuff happens here
delete m_weapon;
if(m_armor != NULL)
delete m_armor;
}
Clearly, this happens because the pointer for weapon didn't get initialized to either NULL or an instance of Weapon object. The constructor also doesn't appear to allow for a default of NULL (at least from what I can see) in the event that one Builder method is omitted from the chain. For now, the client must either give Weapon a pointer to NULL or an instance of an object.
Is there any possible way to get around this without revising this Builder constructor completely? Or, should this be refactored using another pattern, such as Factory, and just go back to a regular constructor with positional parameter list?
I sample code you referred isn't very good code base, I would simply suggest below build pattern:
class Builder
{
Weapon* BuildWeapon() { return new Weapon(); }
Armor* BuildArmor(); { return new Armor(); }
};
class Player
{
public:
Player(const Builder& builder)
: weapon_ptr(builder.BuildWeapon()),
armer_ptr(builder.BuildArmor())
private:
std::shared_ptr<Weapon> weapon_ptr;
std::shared_ptr<Armor> armor_ptr;
};
usage:
Builder builder;
std::shared_ptr<Player> player(new Player(builder));
Or you could just
class Player2
{
public:
Player() {}
void SetWeapon(Weapon* p) { weapon_ptr.reset(p); }
void SetArmor(Armor* p) { armor_ptr.reset(p); }
private:
std::shared_ptr<Weapon> weapon_ptr;
std::shared_ptr<Armer> armer_ptr;
};
usage:
Builder builder;
std::shared_ptr<Player> player;
player->SetWeapon(builder.BuildWeaper());
player->SetArmor(builder.BuildArmor());
As weapon_ptr, armer_ptr are smart pointers, there is no need to call delete for the dynamically allocated memory anymore, thus cleanMemory() function can be removed.
This is just a simple sample, you could expand the Player's interfaces to provide ability to build different element after player object is created.

How to call virtual function of an object in C++ [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Overriding parent class’s function
I'm struggling with calling a virtual function in C++.
I'm not experienced in C++, I mainly use C# and Java so I might have some delusions, but bear with me.
I have to write a program where I have to avoid dynamic memory allocation if possible. I have made a class called List:
template <class T> class List {
public:
T items[maxListLength];
int length;
List() {
length = 0;
}
T get(int i) const {
if (i >= 0 && i < length) {
return items[i];
} else {
throw "Out of range!";
}
};
// set the value of an already existing element
void set(int i, T p) {
if (i >= 0 && i < length) {
items[i] = p;
} else {
throw "Out of range!";
}
}
// returns the index of the element
int add(T p) {
if (length >= maxListLength) {
throw "Too many points!";
}
items[length] = p;
return length++;
}
// removes and returns the last element;
T pop() {
if (length > 0) {
return items[--length];
} else {
throw "There is no element to remove!";
}
}
};
It just makes an array of the given type, and manages the length of it.
There is no need for dynamic memory allocation, I can just write:
List<Object> objects;
MyObject obj;
objects.add(obj);
MyObject inherits form Object. Object has a virtual function which is supposed to be overridden in MyObject:
struct Object {
virtual float method(const Input& input) {
return 0.0f;
}
};
struct MyObject: public Object {
virtual float method(const Input& input) {
return 1.0f;
}
};
I get the elements as:
objects.get(0).method(asdf);
The problem is that even though the first element is a MyObject, the Object's method function is called. I'm guessing there is something wrong with storing the object in an array of Objects without dynamically allocating memory for the MyObject, but I'm not sure.
Is there a way to call MyObject's method function? How? It's supposed to be a heterogeneous collection btw, so that's why the inheritance is there in the first place.
If there is no way to call the MyObject's method function, then how should I make my list in the first place?
Also I have no access to libraries outside of math.h and stdlib.h, so vector is not available for example.
You need to store pointers in the list. Try this:
List<Object*> objects;
Object *obj1 = new Object;
MyObject *obj2 = new MyObject;
Object *obj3 = new MyObject;
objects.add(obj1);
objects.add(obj2);
objects.add(obj3);
// This calls the implementation in Object class
objects.get(0)->method(asdf);
// This calls the implementation in MyObject class
objects.get(1)->method(asdf);
// This calls the implementation in MyObject class
// Polymorphism here
objects.get(2)->method(asdf);
Hope this helps.
When you do this:
objects.add(obj);
you are adding a copy of the Object part of the MyObject to the list, so it is no longer a MyObject.
You might be tempted to try doing this:
int add(T const &p) {
if (length >= maxListLength) {
throw "Too many points!";
}
items[length] = p; // now the problem is here
return length++;
}
but now the copy of the Object part of p happens during the assignment.
To make the list be heterogeneous, it is going to have to be a list of pointers, but you also wanted to avoid dynamic memory allocation. You can avoid dynamic memory allocation if you are careful:
Object obj1;
MyObject obj2;
List<Object*> object_ptrs;
object_ptrs.add(&obj1);
object_ptrs.add(&obj2);
 object_ptr.get(1)->method(input);
object_ptr.get(0)->method(input);
but again, you have to be very careful. The list is now pointing to the two objects on the stack. If you return from this function, those two objects will be destroyed. Note that I've purposefully put the list of object pointers after the objects, so that the list will get destroyed before the objects, so the list won't be left pointing to garbage. However, if you return a copy of the list, you would still have a problem.