how can I check if an object exists in C++ - c++

I am trying to write a function that will check if an object exists:
bool UnloadingBay::isEmpty() {
bool isEmpty = true;
if(this->unloadingShip != NULL) {
isEmpty = false;
}
return isEmpty;
}
I am pretty new to C++ and not sure if my Java background is confusing something, but the compiler gives an error:
UnloadingBay.cpp:36: error: no match for ‘operator!=’ in ‘((UnloadingBay*)this)->UnloadingBay::unloadingShip != 0’
I can't seem to figure out why it doesn't work.
Here is the declaration for class UnloadingBay:
class UnloadingBay {
private:
Ship unloadingShip;
public:
UnloadingBay();
~UnloadingBay();
void unloadContainer(Container container);
void loadContainer(Container container);
void dockShip(Ship ship);
void undockShip(Ship ship);
bool isEmpty();
};

It sounds like you may need a primer on the concept of a "variable" in C++.
In C++ every variable's lifetime is tied to it's encompassing scope. The simplest example of this is a function's local variables:
void foo() // foo scope begins
{
UnloadingShip anUnloadingShip; // constructed with default constructor
// do stuff without fear!
anUnloadingShip.Unload();
} // // foo scope ends, anything associated with it guaranteed to go away
In the above code "anUnloadingShip" is default constructed when the function foo is entered (ie its scope is entered). No "new" required. When the encompassing scope goes away (in this case when foo exits), your user-defined destructor is automatically called to clean up the UnloadingShip. The associated memory is automatically cleaned up.
When the encompassing scope is a C++ class (that is to say a member variable):
class UnloadingBay
{
int foo;
UnloadingShip unloadingShip;
};
the lifetime is tied to the instances of the class, so when our function creates an "UnloadingBay"
void bar2()
{
UnloadingBay aBay; /*no new required, default constructor called,
which calls UnloadingShip's constructor for
it's member unloadingShip*/
// do stuff!
} /*destructor fires, which in turn trigger's member's destructors*/
the members of aBay are constructed and live as long as "aBay" lives.
This is all figured out at compile time. There is no run-time reference counting preventing destruction. No considerations are made for anything else that might refer to or point to that variable. The compiler analyzes the functions we wrote to determine the scope, and therefore lifetime, of the variables. The compiler sees where a variable's scope ends and anything needed to clean up that variable will get inserted at compile time.
"new", "NULL", (don't forget "delete") in C++ come into play with pointers. Pointers are a type of variable that holds a memory address of some object. Programmers use the value "NULL" to indicate that a pointer doesn't hold an address (ie it doesn't point to anything). If you aren't using pointers, you don't need to think about NULL.
Until you've mastered how variables in C++ go in and out of scope, avoid pointers. It's another topic entirely.
Good luck!

I'm assuming unloadingShip is an object and not a pointer so the value could never be NULL.
ie.
SomeClass unloadingShip
versus
SomeClass *unloadingShip

Well, you don't have to write so much code to check if a pointer is NULL or not. The method could be a lot simpler:
bool UnloadingBay::isEmpty() const {
return unloadingShip == NULL;
}
Plus, it should be marked as "const" because it does not modify the state of the object and can be called on constant instances as well.
In your case, "unloadingShip" is an object of class "UnloadingShip" which is not dynamically allocated (except when the whole class "UnloadingBay" is allocated dynamically). Thus, checking if it equals to NULL doesn't make sense because it is not a pointer.

For checking, if an object exists, you can consider going this way:
create a pointer to your object:
someClass *myObj = NULL // Make it null
and now where you pass this pointer, you can check:
if(!myObj) // if its set null, it wont pass this condition
myObj = new someClass();
and then in case you want to delete, you can do this:
if(myobj)
{
delete myObj;
myObj = NULL;
}
so in this way, you can have a good control on checking whether your object exists, before deleting it or before creating a new one.
Hope this helps!

Related

Return object with 2 optional ctors in function

I have function in c++ with 2 optional c'tor of an object I've built (one with something in vector "vals" and other without).
...
RecievedMessage a(sc, type);
if (!vals.empty()){
//a.~RecievedMessage();
RecievedMessage a(sc, type, vals);
}
return &a;
}
the line in // is optional.
Would it work (with or without the optional line)? Why? If no, how to fix it without setter for "vals"?
thanks a lot.
No, it wouldn't work.
RecievedMessage a(sc, type);
// Here we construct 'a'
if (!vals.empty()){
//a.~RecievedMessage();
// If we enable this line, we destroy 'a'
RecievedMessage a(sc, type, vals);
// Here we construct a second 'a' that only exists in this block
}
// End of block: The inner 'a' is destroyed here automatically
return &a;
}
// End of block: The outer 'a' is destroyed here, again.
Destroying an object twice has undefined behavior. You don't want that.
If you don't call the destructor manually, the outer a is only destroyed once, which is good.
But in either case, RecievedMessage a(sc, type, vals); has nothing to do with the outer a and merely creates another variable.
There would be ways to work around that, but the final line of your code makes it all pointless:
return &a;
You're returning the address of a local variable. This is broken in and of itself: When the function returns, all of its local variables are destroyed automatically, so what you're returning is an invalid pointer.
Your code is all over the place, but what I think you're looking for is something like this:
ReceivedMessage *MakeReceivedMessage (foo sc, bar type, vector<whatever>& vals)
{
if (vals.empty())
return new ReceivedMessage (sc, type);
return new ReceivedMessage (sc, type, vals);
}
Of course, it would be better in this example to just have a single constructor and have the object test whether vals is empty when appropriate, but, in general, you can call whatever constructor you like whenever you like. Just manage your object lifetimes properly (and don't - ever - return a pointer to an object on the stack).
Example usage (to manage the lifetime of the object returned properly):
std::unique_ptr<ReceivedMessage> MyReceivedMessage (MakeReceivedMessage (...));
MyReceivedMessage->DoFunkyStuffWithMessage ();
....
Or, as melpomene points out, you can return a std::unique_ptr<ReceivedMessage> in the first place. Some (many?) would prefer that. You can construct it with std::make_unique.
There are three main issues with your code right now:
First of all, your commented out call to the destructor ~ReceivedMessage() should not be there at all. In C++, the destructor of objects is automatically called when an object's lifetime ends (either when it goes out of scope, or when delete is called if it was dynamically allocated with new). While there are some situations where explicitly calling a destructor is necessary ("placement new" for example), these are situations you're very unlikely to come across.
Secondly, your RecievedMessage a(sc, type, vals); declaration in the inner if does not replace the value of a in the outer scope. This just creates another variable of the same name which shadows the outer a, while return &a; in the outer scope can only refer to the outer a. The inner a no longer exists at this point as it has gone out of scope.
A way to fix this issue is to instead assign a new value to a by using the = operator and constructing a temporary ReceivedMessage:
if (!vals.empty()) {
a = ReceivedMessage(sc, type, vals);
}
This should work as long as a correct operator= is defined (implicitly or otherwise) for ReceivedMessage.
Thirdly, your function is returning a pointer to the local variable a. Since objects in C++ are destroyed as soon as they go out of scope, a no longer exists by the time the function has returned, so the ReceivedMessage * pointer the calling code obtains is invalid and it would be undefined behaviour to dereference that pointer and make use of it.
There are a couple of fixes to this issue:
The first option is instead of returning a pointer (ReceivedMessage *), just return a ReceivedMessage by value.
ReceivedMessage foo()
{
ReceivedMessage a(123);
return a;
}
This should work as long as a correct copy or move constructor is defined (implicitly or otherwise) for ReceivedMessage.
The second option is to make use of std::unique_ptr, and make your function instead return std::unique_ptr<ReceivedMessage>.
#include <memory>
std::unique_ptr<ReceivedMessage> foo()
{
std::unique_ptr<ReceivedMessage> a;
if (vals.empty()) {
a = std::make_unique<ReceivedMessage>(sc, type);
} else {
a = std::make_unique<ReceivedMessage>(sc, type, vals);
}
return a;
}
The advantage to this approach is that unique_ptr is nullable, so you can create a null unique_ptr without having to construct a ReceivedMessage straight away. Additionally, you can move and assign unique_ptr values safely without having a correct operator= or a correct copy / move constructor defined.
The calling code may look like this, when using unique_ptr:
std::unique_ptr<ReceivedMessage> message = foo();
foo->bar();
as opposed to the following when using ReceivedMessage directly:
ReceivedMessage message = foo();
foo.bar();

Is it possible to avoid the GC for delegates?

Is it possible to avoid the GC for delegates?
I am building a task system. I have N-Threads with a local task queue. A task queue is basically just a Array!Fiber tasks. Because it is discouraged to send fibers to a different thread, I am sending a closure/delegate to a thread, create the fiber from that delegate and put it in the array tasks.
Now the delegates that I am sending are delegates that capture variables.
//Some Pseudo code
auto f = //some function;
auto cell = Cell(...);
auto del = () {
let res = f();
cell.write(res);
}
send(del);
}
Now cell is heap allocated and synchronized with an atomic counter. I can then check if the atomic counter from cell has reached 0, if it did I can safely read from it.
The problem is that delegates which capture variables, allocate the variables on the GC. Now I only allocate a pointer and it is probably not a huge problem but I would still like to avoid the GC.
How would I do this?
You might already know all this, but this is a bit of a FAQ so I'm going to write a few details.
First, let's understand what a delegate is. Like how a slice is just a C data pointer paired with a length, a delegate is just a C data pointer paired with a function pointer. These are passed together to functions expecting them, as if it was defined
struct d_delegate {
void* ptr; // yes, it is actually typed void*!
T* funcptr; // this is actually a function pointer
};
(Note that the fact that there is just one data ptr in there is the reason behind some compiler errors when you try to take a nested delegate inside a class method!)
That void* is what points to the data and like with a slice, it can come from a variety of places:
Object obj = new Object();
string delegate() dg = &obj.toString;
At this point, dg.ptr points to obj, which happens to be a garbage collected class object, but only because I newed it above.
struct MyStruct {
string doSomething() { return "hi"; }
}
MyStruct obj;
string delegate() dg = &obj.doSomething;
In this case, obj lives on the stack due to how I allocated it above, so the dg.ptr also points to that temporary object.
Whether something is a delegate or not says nothing about the memory allocation scheme used for it - this is arguably dangerous because a passed delegate to you might point to a temporary object that will disappear before you're finished with it! (That's the main reason why GC is used by the way, to help prevent such use-after-free bugs.)
So, if delegates can come from any object, why are they assumed to be GC so much? Well, the automatically generated closure can copy local variables to a GC segment when the compiler thinks the lifetime of the delegate is longer than the outer function.
void some_function(void delegate() dg);
void foo() {
int a;
void nested() {
a++;
}
some_function(&nested);
}
Here, the compiler will copy the variable a to a GC segment because it assumes some_function will keep a copy of it and wants to prevent use-after-free bugs (which are a pain to debug as it frequently leads to memory corruption!) as well as memory leaks.
However, if you promise the compiler that you'll do it right yourself by using the scope keyword on the delegate definition, it will trust you and leave the locals right where they are:
void some_function(scope void delegate() dg);
Keeping the rest the same, it will no longer allocate a copy. Doing it on the function definition side is the best because then you, as the function author, can ensure you don't actually keep a copy.
On the usage side though, you can also label it scope:
void foo() {
int a;
void nested() {
a++;
}
// this shouldn't allocate either
scope void delegate() dg = &nested;
some_function(&dg);
}
So, the only time memory is automatically allocated by the GC is when local variables are used by a nested function which has its address taken without the scope keyword.
Note that the () => whatever and () { return foo; } syntaxes are just shorthand for a named nested function with its address being automatically taken, so they work the same way as the above. dg = {a++;}; is the same as dg = &nested; above.
Thus, the key takeaway from this for you is that if you want to manually allocate a delegate, you just need to manually allocate an object and make a delegate from one of its methods instead of automatically capturing variables! But, you need to keep track of the lifetime and free it properly. That's the tricky part.
So for your example:
auto del = () {
let res = f();
cell.write(res);
};
you might translate that into:
struct Helper {
T res;
void del() {
cell.write(res);
}
}
Helper* helper = malloc(Helper.sizeof);
helper.res = res; // copy the local explicitly
send(&helper.del);
Then, on the receiving side, don't forget to free(dg.ptr); when you're done so you don't leak it.
Or, better yet, if you can change send to just actually take Helper objects, you don't need to allocate it at all, you can just pass it by value.
It also occurs to me that you could pack some other data in that pointer to pass other data in-place, but that'd be abi hacking and possibly undefined behavior. Try it if you wanna play though :)

C++ NULL pointers and const correctness

I read that it is good practice to do a check in the destructors of classes after deletion for pointer data members as follows:
if( 0 != m_pPointer)
{
delete m_pPointer;
m_pPointer= 0;
}
However, I found out that this prevents you to declare const pointers as data members as follows:
Type* const m_pPointer;
Isn't assigning NULL to pointers(as in my example above) a barrier for const-correctness?
What is the best way to do? Keep everything const and stop assigning NULL to the deleted pointer or declaring non-const pointers even though their address never changes?
This is bad practice for the following reasons:
Setting a pointer to null in the destructor may mask double destruction problem. Good practise is to detect problems as early as possible.
Checking a pointer for null before deleteing it only adds unnecessary code. delete handles null pointers by doing nothing. Good practice is to minimize the amount of code.
Deleting a null pointer is guaranteed safe, so that null check is pointless.
If a class has a member that is a const pointer to a non-const object then you're saying the pointer value WILL NOT change within the lifetime of the wrapping object - that being the case you should only do this in the case where the object pointed to will live as long or longer than the wrapping object and the wrapping object will never want to point to a different object.
The fact that you have this issue simply means you've used a const pointer in the wrong place. You claim that in your case the pointer value never changes, but in your example it obviously does - it changes to null.
The "best way to do" is:
class foo {
std::unique_ptr<bar> m_pPointer;
public:
foo(std::unique_ptr<bar> pPointer)
: m_pPointer{std::move(pPointer)} {}
};
or for const,
class foo {
const std::unique_ptr<bar> m_pPointer;
public:
foo(std::unique_ptr<bar> pPointer)
: m_pPointer{std::move(pPointer)} {}
};
No new, no delete, no destructor.
A weird situation can be caused when you link a static lib with a global or static object from two different shared libs (on Linux) which later be linked to the same executable.
Each shared lib object insert call to constructor and destructor, so you'll have one object and two calls for constructor and destructor for the same object (actually you'll have 2 objects mapped to the same address).
You'll probably find the problem when your app crash in the 2nd destructor.
if you NULL it you'll never know that there was a problem at all.
for your question: except for the above issue, I think you should distinct two types of pointers:
See the class below:
class A{
obj *x, *y;
A(){
x = new obj;
y = NULL
}
~A(){
delete x;
if(y)delete y; // the `if` here will save the calling and returning run time when NULL.
}
void RecicleX(){
delete x;
x = new obj;
}
void InitY(){
assert(y==NULL); //illegal to call init when already
y = new obj;
}
void TermY(){
assert(y); //illegal to call term when already inited
delete y;
y = NULL; //prevent crush in dtor if called after...
}
};
x is always exists, so no need to check it, and no need to null it. y may exists and may not, so I think you should null it after deletion.
(You maybe will want also to know the current state, like for assert)

c++ breaks on class function

i have created this class for mesh loading it works but i added this new function to help speed up the loading. when i call the function my program breaks/stops.
here is my function
bool CXFileEntity::LoadXFile(const std::string &filename, int startAnimation, CXFileEntity *entity, LPDIRECT3DDEVICE9 d3ddev)
{
// We only support one entity so if it already exists delete it
if (entity)
{
delete entity;
entity=0;
}
// Create the entity
entity=new CXFileEntity(d3ddev);
if (Load(filename))
{
delete entity;
entity=0;
return false;
}
SetAnimationSet(startAnimation);
return true;
}
EDIT: Wait... I hadn't realized that this function is a member of the CXFileEntity class. It doesn't look like it's a static method, either. So in order to call this function, you already need to have instantiated a CXFileEntity object! Therefore, it's likely that you absolutely do not want to be either deleting or creating CXFileEntity objects inside of this method. (If you truly only allow one entity to exist at a time, you'll be effectively deleting 'this' and then trying to re-create it. That doesn't work, no way, no how.)
I'm leaving the earlier answer in place in hopes that it will still provide you some clue about how pointers work.
You'd do better to give more information, such as where and how the program breaks.
But this is clearly wrong:
CXFileEntity *entity,
because it means that the new object allocated by
entity=new CXFileEntity(d3ddev);
will not be seen by the caller. (entity is a local variable, so changes to it won't be seen outside of the local scope.)
Try changing the code to pass entity as a pointer to a pointer:
CXFileEntity **entity,
which will mean changing the code inside the function to match:
if (*entity)
{
delete *entity;
*entity=0;
}
// Create the entity
*entity=new CXFileEntity(d3ddev);
// etc.
You'll also have to change the caller to pass a pointer to a pointer. And for goodness' sake, make sure that the first time you pass the pointer in, it's initialized to 0:
CXFileEntity *the_entity = 0;
...

How to make object pointer NULL without setting it explicitly, without deleting explicitly and without static functions?

I am working on a c++ application.
In my code i have an object pointer like
TestClass *pObj = new TestClass();
and Member function call like pObj->close();
Inside close() member function, i should make pObj to NULL.
As per our requirement, TestClass users should not call delete on pObj.(Destructor of TestClass is made private intentionally for this purpose)
Also, TestClass should not expose any static method to receive a pointer and making it NULL.
Is there any other way to make pObj to NULL once close() is called ?
I tried one way.
Inside close() function, i removed constness for this pointer using const_cast.
and took a reference of it.
Then i made this = NULL.
Even then calling side, pObj pointer value remains. It is not getting set to NULL.
It may be due to the Address of this pointer and Address of pObj are different.
Pls help.
EDIT: Sorry, i missed something. new is getting called inside a static function called init. init function is like below. void init(TestClass *& pObj); So TestClass user calls init first for allocation. But he can't call deinit(there should not be any such function) Actually, this is not my design. It was present when i entered this project :(
Imagine such code:
TestClass *ptr1 = new TestClass();
TestClass *ptr2 = ptr1;
ptr2->close();
Which pointer do you want to be set to null? Inside close method you have no information how many pointers point to your object and how is close method accessed.
There's no way of doing what you want, given your constraints.
One warning: what happens if the user of your class creates on object on the stack: TestClass test;?
One question more, why do you want the users of your class being forced to call new to allocate objects of your class, but then being forbid to call delete. Makes no sense to me.
An insane problem requires an insane solution, so here is one. You can't do exactly what you want, since it's impossible to keep track of the raw pointers to your object. However, if you use some kind of smart pointer, then they can be tracked and nullified when the object is destroyed. This is a common requirement in less insane circumstances, so there are already smart pointers to do this: shared_ptr to keep the object alive, and weak_ptr to track the object and go null when it's destroyed. So the solution would look something like this:
class TestClass
{
public:
static weak_ptr<TestClass> create()
{
shared_ptr<TestClass> shared(new TestClass);
shared->self = shared;
return shared;
}
void close()
{
self.reset();
}
private:
shared_ptr<TestClass> self;
};
int main()
{
weak_ptr<TestClass> object = TestClass::create();
weak_ptr<TestClass> copy = object;
assert(!object.expired());
assert(!copy.expired());
object.lock()->close();
assert(object.expired());
assert(copy.expired());
}
As per our requirement, TestClass users should not call delete on pObj.(Destructor of TestClass is made private intentionally for this purpose) Also, TestClass should not expose any static method to receive a pointer and making it NULL.
Who set those requirements? For each of them, ask "Why?". They seem absolutely arbitrary, they make no sense.
and Member function call like pObj->close(); Inside close() member function, i should make pObj to NULL.
Again, "Why?". Disregarding changing this from inside of a function is not possible, using such style is crazy. A normal C++ way is to destruct the object instead.
If you will get no reasonable answer to your "whys", you should probably consider quitting the job, or prepare to spend your time there in frustration. The design "requirements" you have presented are really extraordinary crazy.
No. Consider the following code:
TestClass * const pObj = new TestClass();
pObj->close();
The compiler will not reject the code, even if close would be const. The pointer is const, but not the new TestClass object. Therefore you can call non-const methods via the pointer, but you can't change the pointer itself. That means you can't set it to NULL either.
It basically means that you need to set this pointer to NULL. This is not possible as far as I know. If it helps you can think the calling of the method taking this pointer by value i.e. whatever change you do inside the method will not be reflected outside.
while you're writing terrible code you may as well add some inline assembly and xor ecx,ecx just before you return from close().
Probably won't work unless you happen to be super careful with the pObj init returns to not to anything fancy with it.
#include <map>
std::map<TestClass*, TestClass**> pointers();
void init(TestClass *& pObj)
{
pObj = new TestClass();
pointers[pObj] = &pObj;
}
void TestClass::Close()
{
*pointers[this] = null;
pointers.erase(this);
delete this;
}
Though, it is full of dangers, a way could be
TestClass::Close(Testclass *&p){
p = NULL;
}
pObj->close(pObj);
EDIT: After explanation on restriction of Close();
Is pObj accessible in scope of 'TestClass::Close'? e.g. a namespace scope variable?
If yes, the TestClass::Close method can simply set pObj = NULL;
If no, there is no way IMHO