Make Pointer Getter use unique_ptr - c++

sf::RectangleShape* operator()()
{
return &player;
} // RectangleShape Getter
Do I need to free memory after this getter? If yes, how would one do this with unique_ptr?
I tried
std::unique_ptr<sf::RectangleShape> operator()()
{
return std::unique_ptr<sf::RectangleShape>(player);
} // RectangleShape Getter
But it says there is no matching function for the parenthesis operator. How else should this be done?

sf::RectangleShape* operator()()
{
return &player;
} // RectangleShape Getter
Do I need to free memory after this getter?
All you do is return a pointer to player. Assuming that is a member variable of the struct/class the above member function is a part of, then its lifetime is bound to the lifetime of the object you call that function with.
In particular that means that this is a bad idea:
struct Foo {
sf::RectangleShape player;
// ...
// insert your operator here
};
sf::RectangleShape * some_function(void) {
Foo f;
return f(); // UB, returning pointer to object with automatic memory whose lifetime has ended
}
[..] how would one do this with unique_ptr?
Assuming sf::RectangleShape has a copy constructor, then you could make a copy of player:
std::unique_ptr<sf::RectangleShape> operator()() {
return make_unique<sf::RectangleShape>(player);
}
The copy you get that way is "yours", i.e. you can manage is lifetime as you want.

It seems like player is member of a class and you are trying to hand out a pointer to it for it to modified outside the class?
In this case, the class it belongs to owns the memory and it is down to that class to handle freeing the data when it is destroyed. A pointer to that member should absolutely not be freed from outside the class.
It would help to have more information about the owning class, but if I can assume that player is a data member, then your first example is technically fine. However it is often more idiomatic to return a reference than pointer.
class SomeClass
{
sf::RectangleShape player;
sf::RectangleShape& operator()()
{
return player;
}
};
If the above assumption is incorrect, you should show your full class definition so we have more information to form a correct solution.

Related

Binding temporary to r-value reference produces error

I'm trying to write a pImpl without using a unique_ptr. I don't understand while writing something like this:
class PublicClass
{
public:
// Some stuff
PublicClass();
private:
class ImplClass;
ImplClass&& mImpl;
};
class PublicClass::ImplClass
{
public:
ImplClass() {}
};
PublicClass::PublicClass() : mImpl(ImplClass()){}
produces following compilation error
Reference member 'mImpl' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object
while writing the following
PublicClass::PublicClass() : mImpl(std::move(ImplClass())){}
is ok. R-value references should not extend life-time of temporaries, as in first snippet?
From class.temporary:
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
A temporary bound to a reference member in a constructor's ctor-initializer ([class.base.init]) persists until the constructor exits.
This is applicable to both of your examples. That is, in both of your given cases you have a dangling reference. Its just that in case 2 of your example the compiler is not able to give us the appropriate error/warning.
First of all you must understand that every object requires the storage. You have 3 storages:
Stack
Heap
Static storage (the place where global variables are defined)
Both PublicClass and PublicClass::ImplClass are classes and to create an instance of this class you need the storage.
So you first decide where do you want to allocate the ImplClass.
In case if you want to be able allocate both PublicClass and PublicClass::ImplClass on the stack, compiler must know the size of the ImplClass at compile time. I mean you cannot allocate the object on the stack if the size of the object is not known at compile time at the point where object is created. What you can do is to pre-allocate the memory using char[N] variable
class PublicClass
{
// must be large enough to fit the ImplClass
static constexpr auto PublicClassImplSize = 128;
// The storage for ClassImpl
char alignas(void*) impl_[PublicClassImplSize];
class ImplClass;
public:
PublicClass();
~PublicClass();
};
// cpp
#include <new>
class PublicClass::ImplClass
{
char buf1[10];
// char buf2[10000];
};
PublicClass::PublicClass()
{
static_assert(sizeof(ImplClass) <= PublicClassImplSize);
new (impl_) ImplClass();
}
PublicClass::~PublicClass()
{
reinterpret_cast<ImplClass*>(impl_)->~ImplClass();
}
int main()
{
PublicClass o;
}
In case if you do not care where ImplClass is allocated, you can allocate it on the heap. In this case you use new/delete operators to allocate/release the memory and implement RAII inside the PublicClass to manage the resource.
unique_ptr is an example of the RAII-class. If for any reason you do not want to use it, you must implement the RAII inside the PublicClass. I.e. you implement constructor which allocates the ClassImpl on the heap and you implement the destructor, which releases the resources. You also have to care about move/copy constructors and move/assignment operators, as default behaviour provided by C++ language does not work right here.
class PublicClass
{
class ImplClass;
ImplClass* impl_{nullptr};
public:
PublicClass();
~PublicClass();
PublicClass(PublicClass&&) noexcept;
PublicClass& operator=(PublicClass&&) noexcept;
};
// cpp
#include <new>
#include <memory>
class PublicClass::ImplClass
{
char buf1[10];
// char buf2[10000];
};
PublicClass::PublicClass()
{
auto impl = std::make_unique<ImplClass>();
// ... more initialization
// Initialization is completed
impl_ = impl.release();
}
PublicClass::PublicClass(PublicClass&& obj) noexcept
: impl_(std::exchange(obj.impl_, nullptr))
{
}
PublicClass& PublicClass::operator=(PublicClass&& obj) noexcept
{
delete impl_;
impl_ = std::exchange(obj.impl_, nullptr);
return *this;
}
PublicClass::~PublicClass()
{
delete impl_;
}
int main()
{
PublicClass o;
}
In case if by design you have only one instance of the object, you can allocate the ClassImpl in the global namespace. Personally, I do not like this solution.
Update
I mean you cannot allocate the object on the stack if the size of the object is not known at compile time at the point where object is created
The use of alloca function is out of scope :)

Act upon an object calling a function?

So say I was using this to create an object:
MyClass myObject;
and I had the function inside of the class to act upon the object. So one way could be using parameters, like this:
MyClass foo(MyClass a) {
return a;
}
Seems simple. But is there a way so I can use myObject.foo() and it would still return a even though I'm not using it as a parameter? One example could be some of the methods in std::string - you can use std::string.swap(), using the object for the swap() function.
Is there a way, or am I being stupid?
First off, keep in mind that you original code of
MyClass foo(MyClass a) {
return a;
}
does not actually return a. It returns a copy of a, which itself is a copy of whatever instance of MyClass you passed into foo. If you want to pass in a given object, act on it and return it, you need to use references, like so
MyClass & foo(MyClass & a) {
return a;
}
This will ensure that the a you get back from a call to foo is the exact same object you passed into it.
Additionally, an object can always return a reference to itself in one of its members...
class MyClass {
MyClass & foo() { return *this; }
}
This is especially useful in classes where you might want to chain a large number of operations together...
MyClass my = MyClass().foo().bar("Hello").baz(5);
Inside every member function is a magic secret parameter, which is a pointer to the object who's method was called, and the parameter's name is this.
MyClass& foo() { //returns reference to existing MyClass instead of making copies
this->print(); //call a different member
return *this; //return a reference to itself. Common for `operator=` and such.
}
Inside a class's (non-static) member function, you can use *this to name the object the function was called on.
So:
MyClass MyClass::foo() {
return *this;
}
(Notice that function returns a copy of the object. If you don't want a copy, use a reference as in #Jherico's answer.)

How to pass a vector of objects to another class then call a function from within a member of an object in that vector?

How to pass a vector via a function call to a pointer to a vector in another class and call a function or element via the receiving class; and how to call that function in the receiving class remotely?
In this example, object0 is an object type containing a function that will be called.
Object0 will be created in object1 as a member of a vector.
Then that vector will be passed to object2, wherein it will be called from an external object; here arbitrarily chosen as within object1;
main() is just a way of booting this app up, and I would welcome suggestions on improving it.
#include <vector>
class object0
{
protected:
int a;
void function()
{
std::cout << "function called" << std::endl;
}
};
class object2
{
public:
std::vector<object0> *object0vec;
void knowvector(std::vector<object0> *_object0vec)
{
object0vec = _object0vec;
}
};
class object1
{
public:
object2* _object2;
object1()
{
_object2 = new object2;
}
void init()
{
std::vector<object0> object0vec;
object0vec.push_back(new object0)
_object2.object0vec[0].function();
How to get this line working? _object2.object0vec[0].function();
}
};
int main()
{
object1 newobject1;
object1 &ref_newobject1 = newobject1;
ref_newobject1.init();
}
In init():
"_object2" has lifetime the same as object1.
Yet, in init() you presumably will pass a pointer to the local variable object0vec to knowvector().
So now, "_object2" has a longer lifetime than an object it has a poiner to, yet doesn't own.
"knowvector" could make a copy of the vector instead of keeping a pointer.
Syntax:
In Init(), "_object2" is a pointer, so you need to use ->.
object2::object0vec is also a pointer while presumably "object0vec[0]" is meant to get the first object in the vector, not the first in an array of vectors.
_object2 -> (*object0vec)[0].function();

c++ std::bind keeping object alive

Here is the code, it's pretty straightforward.
class Foo
{
public:
void print()
{
std::cout<<"Foo::print\n";
}
};
Game::Game()
{
{
Foo foo;
player.onclick = bind(&Foo::print,foo);
}
player.onclick();
}
After the inner scope is done the foo object goes out of scope, but the print method is still called, I guess this happens because player holds a reference to the foo object? Is there a way to stop this from happening? I don't want objects to stay alive and receive events when they are supposed to be destroyed.
Thanks.
You are binding to a copy of foo; that copy lasts as long as the bound function object, while the original foo is destroyed at the end of its scope.
If you don't want to keep it alive, then bind to a pointer (&foo) or a reference (std::ref(foo)); and then you must be careful not to call the function object once foo has gone out of scope. Note that there's no way to tell from the function object that this has happened; calling it will give undefined behaviour.
In order to safely disconnect the object when it's destroyed, you would have to either arrange for its destructor to reassign onclick, or make some other object responsible for first reassigning onclick, and then destroying the object.
From your description it sounds like you actually want an event loop. While std::bind is useful for something like that it isn't one all by itself. I suggest you have a look at boost.signals
I think you should use shared_ptr when you assign Foo to Player, and keep a weak_ptr to Foo in Player. Then try to lock the weak_ptr in the onclick function to see if Foo is still alive. Something like this:
using namespace std;
class Foo
{
public:
void print()
{
cout<<"Foo::print\n";
}
};
class Player
{
public:
weak_ptr<function<void()>> _onClickFuntion;
void onclick()
{
shared_ptr<function<void()>> tempFunction(_onClickFunction.lock());
if (tempFunction)
tempFunction();
}
}
Game::Game()
{
{
Foo foo;
player._onClickFuntion = shared_ptr<function<void()>>(new bind(&Foo::print,foo));
}
player.onclick();
}

My virtual function wont work C++

I have edited this from my real code, so that it is a little easier to understand.
The base class:
class MWTypes
{
public:
virtual long get() { return (0); }
};
The derived class: (There are going to be other classes like char, double etc etc . . .)
class TypeLong : public MWTypes
{
public:
TypeLong(long& ref) : m_long(ref) {}
~TypeLong();
long get() { return m_long; }
private:
long& m_long;
};
and the storage class:
class RowSet
{
public:
void addElememnt(MWTypes elem);
MWTypes getElement();
std::vector<MWTypes> getVector() { return m_row; }
private:
std::vector<MWTypes> m_row;
};
How it is called:
for (i = 0; i < NumCols; i++) // NumCols is 3 on this instance
{
switch(CTypeArray[i]) // this is an int which identifies the type
{
case SQL_INTEGER:
{
long _long = 0;
TypeLong longObj(_long);
MWTypes *ptr = &longObj;
// some SQL code goes here that changes the value of _long,
// there is no need to include it, so this will do.
_long++;
// I now want to save the data in a vector to be returned to the user.
rowSet.addElememnt(*ptr);
///////////////////////////////////////////////
// some code happens here that is irrelevant //
///////////////////////////////////////////////
// I now want to return the typr I have saved in the vector,
// I THINK I am doing this right?
MWTypes returned = rowSet.getElement();
// lastly I want to get the value in the returned type
long foo = returned.get();
///////////////////////////////////////////////
// some code happens here that is irrelevant //
///////////////////////////////////////////////
I think I am on the right lines here. The value of 'foo' is always 0. I have a feeling this could be the way Im storing in the vector, or it could be the base virtual function, as it always returns 0.
If I remove the return in my base class I get LNK2001 errors.
MWTypes returned = rowSet.getElement();
// lastly I want to get the value in the returned type
long foo = returned.get();
should be
MWTypes* returned = &rowSet.getElement();
// lastly I want to get the value in the returned type
long foo = returned->get();
or
MWTypes& returned = rowSet.getElement(); // actually illegal, but MSVC will let you do
// lastly I want to get the value in the returned type
long foo = returned.get();
Indeed, polymorphic calls must be made via a pointer or a reference.
EDIT: this is not your only problem. The fact that the vector stores objects (and not pointers) will slice the objects and destroy their type information.
See this faq entry for additional info to help you solve your problem and understand how virtual functions are called.
The fundamental problem is that you are making copies of your objects of type MWTypes, thus losing their particular subclass. If you want to use an object of an unknown subclass of the base class, then you can only use a pointer or reference to the base type, not an actual instance of it.
Not providing an implementation of the function "get" as ascanio's code shows (making the function "pure virtual") would prevent you from being able to make this copying mistake, because the compiler would not let you instantiate the class MWTypes if you did that (it would say the class is "abstract").
You are suffering from slicing since your collection stores copies of the base type. Whenever you store something into the vector, your code just slices off the base part and it forgets its original type.
To fix this, you could store pointers to the base: std::vector<MWTypes*>, but then you have to manage your instances correctly to avoid memory leaks.
class RowSet
{
public:
// addElement assumes responsibility for the memory allocated for each 'elem'
void addElement(MWTypes* elem);
MWTypes* getElement();
std::vector<MWTypes*> getVector() { return m_row; }
// Destructor calls delete on every pointer in m_row
~RowSet();
private:
std::vector<MWTypes*> m_row;
};
Then you need to fix your code which calls addElement() to create new instances, and to get the long back again:
rowSet.getElement()->get();
You're problem lies with this function void addElememnt(MWTypes elem);. It should be either void addElememnt(MWTypes* elem); or void addElememnt(MWTypes& elem);. This is because by having an argument to be passed by-value, it loses it's polymorphism. The passing by-value calls the copy constructor of the base class and ONLY copies the contents of the base class (and the vtable) ignoring the rest from the derived class.
Also, if you need to store values of a certain base-class type, you need to consider using a list of pointers of the base-class type.
The problem lies here:
class RowSet
{
public:
void addElememnt(MWTypes elem);
You are taking elem by value, not by pointer or by reference, so the TypeLong subobject is sliced away, here: (reference: What Is The Slicing Problem in C++?)
TypeLong longObj(_long);
MWTypes *ptr = &longObj;
_long++;
rowSet.addElememnt(*ptr);
You need to change addElement to take a reference or a pointer.
Your vector, getElement, and addElememnt parts all invoke object slicing since they store the base object by value. You need to work with pointers or references in order to use runtime polymorphism.
In this case either a boost::ptr_vector or a vector of shared_ptr is probably what you want.