In my program, I have a bunch of objects of a custom class Position. The declaration of Position is as follows:
class Position {
public:
Position(int x, int y);
~Position();
Actor *getActor() { return actor.get(); };
void setActor(Actor *actor) { actor = std::move(actor); };
Actor *clearActor() { return actor.release(); };
int getX() { return x; };
int getY() { return y; };
private:
int x, y;
std::unique_ptr<Actor> actor;
};
I also have a class called Actor. Not every Position will have an Actor, and so the majority of the time the unique_ptr "actor" of a Position object should be empty (I'm using unique_ptrs to automatically clean up any Actor associated with a Position at runtime).
The Position constructor is as follows:
Position::Position(int x, int y)
{
this->x = x;
this->y = y;
actor.reset(nullptr);
}
However, I know that this isn't correctly setting the stored pointer to nullptr because when I try calling actor.get() inside Position::getActor(), I get an error as follows:
First-chance exception at 0x01096486 in ____.exe: 0xC0000005: Access violation reading location 0x00000008.
Is there a way to initialize a member unique_ptr to nullptr? I know I could get around this by adding a variable to the Actor class that defines whether or not the Actor is active, setting the unique_ptr to a new inactive Actor, and ignoring all inactive Actors, but I'd rather avoid this if possible.
Thanks!
Edit: I've added the code where I call getActor:
bool Grid::addActor(Actor *actor, int x, int y)
{
Position *destination = at(x, y);
if (!destination->getActor()) {
destination->setActor(actor);
actor->setPosition(x, y);
actor->setGrid(this);
return true;
}
else {
inactive_actors.emplace_back(actor);
return false;
}
}
Your error is here:
void setActor(Actor *actor) { actor = std::move(actor); };
You're assigning the result of std::move to the parameter actor. You probably meant to reset the member variable actor with the parameter actor:
void setActor(Actor *actor) { this->actor.reset(actor); };
As a side note, you can simply change your constructor to this:
Position::Position(int x, int y)
: x(x), y(y)
{
}
This will initialize the members x and y with the arguments, and default-initialize std::unique_ptr<Actor> actor to null.
You don't need to initialize the std::unique pointer to null. Just leave it as its default empty value in the constructor and only ever reset it to point to a non-null pointer.
Related
In summary, I have a class inherited from std::enabled_shared_from_this, and there is a factory method return an std::unique_ptr of it. In another class, I convert the std::unique_ptr of the previous class object to std::shared_ptr, and then I call shared_from_this(), which then throws std::bad_weak_ptr. The code is shown below:
#include <memory>
#include <iostream>
struct Executor;
struct Executor1 {
Executor1(const std::shared_ptr<Executor>& executor,
int x): parent(executor) {
std::cout << x << std::endl;
}
std::shared_ptr<Executor> parent;
};
struct Backend {
virtual ~Backend() {}
virtual void run() = 0;
};
struct Executor: public Backend, public std::enable_shared_from_this<Executor> {
const int data = 10;
virtual void run() override {
Executor1 x(shared_from_this(), data);
}
};
// std::shared_ptr<Backend> createBackend() {
std::unique_ptr<Backend> createBackend() {
return std::make_unique<Executor>();
}
class MainInstance {
private:
std::shared_ptr<Backend> backend;
public:
MainInstance(): backend(createBackend()) {
backend->run();
}
};
int main() {
MainInstance m;
return 0;
}
Indeed changing std::unique_ptr<Backend> createBackend() to std::shared_ptr<Backend> createBackend() can solve the problem, but as I understand, in general, the factory pattern should prefer return a unique_ptr. Considering a good pratice of software engineering, is there a better solution?
[util.smartptr.shared.const]/1 In the constructor definitions below, enables shared_from_this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_shared_from_this (23.11.2.5), then [magic happens that makes shared_from_this() work for *p - IT]
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
[util.smartptr.shared.const]/29 Effects: ... equivalent to shared_ptr(r.release(), r.get_deleter())...
template<class Y, class D> shared_ptr(Y* p, D d);
[util.smartptr.shared.const]/10 Effects: ... enable shared_from_this with p
Your example executes std::shared_ptr<Backend>(uptr) where uptr is std::unique_ptr<Backend>, which is equivalent to std::shared_ptr<Backend>(p, d) where p is of type Backend*. This constructor enables shared_from_this with p - but that's a no-op, as Backend doesn't have an unambiguous and accessible base class that is a specialization of enable_shared_from_this
In order for Executor::enable_from_this to work, you need to pass to a shared_ptr constructor a pointer whose static type is Executor* (or some type derived therefrom).
Ok, I find a simple solution, that is, using auto as the return type of the factory function, instead of std::unique_ptr or std::shared_ptr, and keeping std::make_unique inside the factory function. The factory function createBackend should be:
auto createBackend() {
return std::make_unique<Executor>();
}
In this case, the return type can be automatically determined, although I don't know how it works exactly. This code can return either unique_ptr or shared_ptr, which should be better than just using shared_ptr. I tested clang and gcc, and both of them worked, but I am still not sure if this is gauranteed by the type deduction and the implicit conversion.
Update:
Actually, I have found that auto deduces the return type above as std::unique_ptr<Executor> instead of std::unique_ptr<Backend>, which might be the reason why the code works. But using auto has an issue: if you return the smart pointer in an if-else block, where the return type varies depending on some parameters, then auto cannot determine the type. For example:
std::unique_ptr<Backend> createBackend(int k = 0) {
if (k == 0) {
return std::make_unique<Executor>();
}
else {
return std::make_unique<Intepreter>();
}
}
Here, both Executor and Intepreter derive from Backend. I think a correct solution includes:
Inherit Backend instead of its derived classes from std::enable_shared_from_this;
Use dynamic_pointer_cast<Derived class> to cast the shared_ptr to derived class after shared_from_this.
The full code is listed in:
https://gist.github.com/HanatoK/8d91a8ed71271e526d9becac0b20f758
In certain cases when programming with libraries written in C involving callbacks, I like to use Lambda expressions; however, if I need to alter the state of a class member variable I can't juts pass this into a stateless(function pointer) lambda. But I can assign this to a data in a context structure. What I find strange is being able to access that member variable even if it's private in the class.
Here's an example code I wrote to demonstrate.
#include <iostream>
using std::cout;
typedef struct extradatatype{
void* data;
}extradata;
extradata e = {0};
typedef void(*callback)(extradata* e);
void cb(callback c){
c(&e);
}
class Test{
private:
int x;
public:
Test(int x){
this->x = x;
}
void setcb(){
cb([](extradata* e){
Test* self = reinterpret_cast<Test*>(e->data);
self->x = 20;
});
}
int getx(){
return x;
}
};
int main(){
Test t(10);
e.data = &t;
t.setcb();
cout << t.getx();
return 0;
}
In the Lambda expression Test* self is assigned to e->data but I can access self->x as if it were a public member instead of private. So what I'm confused about is, is the lambda expression expression being executed within the stack/context of the setcb function or is it being executed elsewhere as its own function but C++ is doing some weird trick to allow private members to be accessed. Because I assume a stateless lambda is really no different than a non member static function which has no access to private members of a class.
Since your lambda function is defined within the class Test context, it will have access to class Test private member (regardless if it's this.x or self.x where self is of type Test). It is similar to this example:
class Example {
private:
int x;
public:
int f(Example e) {
return e.x;
}
};
where, since f is a member of Example, it can access e.x because e has type Example.
If you move your lambda function definition out of the class context you'll see the expected error message:
void outside(extradata* e);
class Test{
private:
int x;
public:
void setcb(){
cb(outside);
}
};
void outside(extradata* e) {
Test* self = reinterpret_cast<Test*>(e->data);
self->x = 20; // error here!
}
test.cpp:32:11: error: 'int Test::x' is private within this context
self->x = 20;
^
#include <iostream>
static int i=0;
using namespace std;
class Movable
{
public:
Movable ():mId(++i){
cout<<"constructing it "<<mId<<endl;
};
Movable (const Movable&)=delete;
Movable (Movable&)=delete;
void operator=(Movable&)=delete;
void operator=(const Movable&)=delete;
Movable (const Movable&& aObject)
{
cout<<"Moving it constant "<<mId<<endl;
// mId=++i;
};
Movable (Movable&&aObject)
{
cout<<"Moving it "<<mId<<endl;
};
Movable &operator=( Movable&&aObject)
{
cout<<"Moving it assignment "<<mId<<endl;
return *this;
}
Movable &operator=(const Movable&&aObject)
{
cout<<"Moving it assignment constant "<<mId<<endl;
return *this;
}
~Movable ()
{
cout<<"destroying it "<<mId<<endl;
}
int getId() const {
return mId;
}
private:
int mId;
};
Movable&& CreatenNewMovable ()
{
Movable lM;
return std::move(lM);
}
int main() {
Movable a;
a=CreatenNewMovable();
return 0;
}
The output result of this code is
constructing it 1
constructing it 2
destroying it 2
Moving it assignment 1
destroying it 1
I'm a little bit confused how is it possible to destroy the temp object then move it to second. Is that an undefined behavior ? m I missing something about the move operation?
Yes, this function
Movable&& CreatenNewMovable ()
{
Movable lM;
return std::move(lM);
}
is broken.
An r-value reference is still a reference, in this case its a reference to a local stack object which is destroyed when the function terminates (before it is moved from). Instead you should just return it by value, it will still get moved out of and if there is copy-ellision then it will be efficient.
Look at this snippet:
Movable&& CreatenNewMovable ()
{
Movable lM;
return std::move(lM);
}
Actually this is Undefined Behaviour. There are 2 problems:
A function can return its value only by value (probably a reference value). So, you must replace Movable&& with Movable here.
Creating Movable lM; on the stack and referencing it outside the function is UB. When the function exits, the object no longer exists. Return it simply by value - in your case copy elision will be in effect.
Finally, a valid way is :
Movable CreatenNewMovable ()
{
Movable lM;
return lM;
// ..or..
// Even better to return like this(copy elision has less chances to fail)
// return Movable();
}
This will produce result you are waiting:
$ ./w
constructing it 1
constructing it 2
Moving it assignment 1
destroying it 2
destroying it 1
You can reduce even this job by removing empty object creation in your main:
int main() {
Movable a=CreatenNewMovable();
return 0;
}
/* Results:
$ ./w
constructing it 1
destroying it 1
*/
I have a custom method that pops an object from a queue of value objects as out parameter and returns an error code:
class Element
{
public:
Element() = delete;
Element(int32_t a, const std::string &s)
{
a_ = a;
s_ = s;
}
private:
int32_t a_;
std::string s_;
}
enum class ErrorCode : uint32_t
{
OK = 0,
QueueEmpty,
QueueFull
}
class QueueWrapper
{
public:
ErrorCode push(const Element &e)
{
// Implementation
}
ErrorCode pop(Element &outE)
{
// Simple example
if(queue_.empty())
{
return ErrorCode::QueueEmpty;
}
outE = queue_.front();
queue_.pop();
return ErrorCode::OK;
}
private
std::queue<Element> queue_;
}
void function()
{
QueueWrapper queueWrapper;
Element e1(1, "1");
ErrorCode errorCode = queueWrapper.push(e1);
// What should I do here?
// Element e2;
// errorCode = queueWrapper.pop(e2);
}
Can I get a non-default constructed object as output parameter using move semantics or other mechanisms?
Change the signature of pop() to return an Element and not an ErrorCode, then:
Element e( queueWrapper.pop() );
If you absolutely have to have the ErrorCode, pass it into pop() by reference. BUT error codes really aren't modern C++. Errors should mostly be handled with exceptions, leading to something more like this:
try {
...
Element e( queueWrapper.pop() );
...
}
catch ( QueueWrapper::Exception & e )
{
// exception handling/reporting
}
Error codes should really only be used for crossing module boundaries.
No. If you can form a reference to an Element, that means it has already be constructed (or it would be a segment of memory gibberish, not an Element).
If the behaviour you want is for the function to somehow get a designated space to construct the object into, let (N)RVO do the job.
How would you set the object data that is shared between threads and needs to be updated once after the complete cycle of (say) two threads in busy loop?
CRITICAL_SECTION critical_section_;
int value; //needs to be updated once after the cycle of any number of threads running in busy loop
void ThreadsFunction(int i)
{
while (true)
{
EnterCriticalSection(&critical_section_);
/* Lines of Code */
LeaveCriticalSection(&critical_section_);
}
}
Edit: The value can be an object of any class.
Two suggestions:
Make the object itself thread safe.
Pass the object into the thread as instance data
I'll use C++ as a reference in my example. You can easily transpose this to pure C if you want.
// MyObject is the core data you want to share between threads
struct MyObject
{
int value;
int othervalue;
// all all the other members you want here
};
class MyThreadSafeObject
{
private:
CRITICAL_SECTION _cs;
MyObject _myojbect;
bool _fLocked;
public:
MyThreadSafeObject()
{
_fLocked = false
InitializeCriticalSection();
}
~MYThreadSafeObject()
{
DeleteCriticalSection();
}
// add "getter and setter" methods for each member in MyObject
int SetValue(int x)
{
EnterCriticalSection(&_cs);
_myobject.value = x;
LeaveCriticalSection(&_cs);
}
int GetValue()
{
int x;
EnterCriticalSection(&_cs);
x = _myobject.value;
LeaveCriticalSection(&_cs);
return x;
}
// add "getter and setter" methods for each member in MyObject
int SetOtherValue(int x)
{
EnterCriticalSection(&_cs);
_myobject.othervalue = x;
LeaveCriticalSection(&_cs);
}
int GetOtherValue()
{
int x;
EnterCriticalSection(&_cs);
x = _myobject.othervalue;
LeaveCriticalSection(&_cs);
return x;
}
// and if you need to access the whole object directly without using a critsec lock on each variable access, add lock/unlock methods
bool Lock(MyObject** ppObject)
{
EnterCriticalSection(&_cs);
*ppObject = &_myobject;
_fLocked = true;
return true;
}
bool UnLock()
{
if (_fLocked == false)
return false;
_fLocked = false;
LeaveCriticalSection();
return true;
}
};
Then, create your object and thread as follows:
MyThreadSafeObject* pObjectThreadSafe;
MyObject* pObject = NULL;
// now initilaize your object
pObjectThreadSafe->Lock(&pObject);
pObject->value = 0; // initailze value and all the other members of pObject to what you want them to be.
pObject->othervalue = 0;
pObjectThreadSafe->Unlock();
pObject = NULL;
// Create your threads, passing the pointer to MyThreadSafeObject as your instance data
DWORD dwThreadID = 0;
HANDLE hThread = CreateThread(NULL, NULL, ThreadRoutine, pObjectThreadSafe, 0, &dwThreadID);
And your thread will operate as follows
DWORD __stdcall ThreadFunction(void* pData)
{
MyThreadSafeObject* pObjectThreadSafe = (MyThreadSafeObject*)pData;
MyObject* pObject = NULL;
while (true)
{
/* lines of code */
pObjectThreadSafe->SetValue(x);
/* lines of code */
}
}
If you want implement thread safe update of an integer you should better use InterlockedIncrement and InterlockedDecrement or InterlockedExchangeAdd functions. See http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx.
If you do need use EnterCriticalSection and LeaveCriticalSection you will find an example in http://msdn.microsoft.com/en-us/library/ms686908(v=VS.85).aspx, but I recommend you to use EnterCriticalSection inside of __try block and LeaveCriticalSection inside of the __finally part of this blocks.