Proper Destructors / RAII / Something - c++

Here's a minimal example of a problem that I'm having, and I can't work out how I should solve it:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing thing;
app.add_thing(&thing);
}
This compiles and runs with no issues, however, upon reaching the end of main, segfaults and spits out:
Error in `/path/testapp': free(): invalid pointer: 0x00007fff97118070 ***
Any possible help? The reason I want to store (unique) pointers is that Thing will usually be derived.
EDIT:
One working solution:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing* thing = new Thing;
app.add_thing(thing);
}
But from what I understand, I should be able to avoid using new entirely, and use make_unique? I can't seem to find where make_unique is actually defined though.
EDIT 2:
Is this more appropriate? Is there a less messy looking way to do this? Otherwise, it works well.
#include <vector>
#include <memory>
#include <iostream>
class Thing {
public:
int foo = 42;
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(std::unique_ptr<Thing>);
};
void App::add_thing(std::unique_ptr<Thing> thing) {
thingVec.push_back(std::move(thing));
}
int main() {
App app;
app.add_thing(std::unique_ptr<Thing>(new Thing()));
std::cout << app.thingVec.back()->foo << std::endl;
}
Because I may end up with lines like
app.thingVex.back()->barVec.back()->blahMap.emplace("flop", std::unique_ptr<Tree>(new Tree));

std::unique_ptr is attempting to delete a stack-allocated Thing instance.
Your error is essentially in the lines:
Thing thing;
app.add_thing(&thing);

The interface to add_thing is wrong because it takes a "non-owning" raw pointer to a Thing and then assumes that it can take full ownership of the object passed in by constructing a unique_ptr from it.
If you change add_thing to take a unique_ptr<Thing> by value, then the caller will be prevented from implicitly converting a raw pointer and will no that they need to construct a new unique_ptr to a heap allocated thing into the add_thing function.
e.g.
void App::add_thing(std::unique_ptr<Thing> thing) {
thingVec.push_back(std::move(thing));
}
int main() {
App app;
app.add_thing(std::make_unique<Thing>());
}
(Note that std::make_unique is a future feature; std::unique_ptr<Thing>(new Thing) works now.)

You should pass local object to unique_ptr.
Replace
Thing thing;
app.add_thing(&thing);
with
app.add_thing(new Thing);
If you want to also edit the object
Thing *thing = new Thing;
// thing->some_val = val;
app.add_thing(thing);
Make sure not to add the same object twice in the app, as std::unique_ptr take the ownership of pointer pointer would be tried to free more than 1 time.

You are transferring the ownership not properly. You might utilize a shared pointer with a custom deleter to the prevent deletion of the referenced variable:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::shared_ptr<Thing>> thingVec;
void add_thing(std::shared_ptr<Thing>&& thing) {
thingVec.push_back(std::move(thing));
}
};
template<typename T>
inline std::shared_ptr<T> make_no_delete(T& value)
{
return std::shared_ptr<T>(&value, [](void*){});
}
int main() {
App app;
Thing thing;
// Add without transferring ownership:
app.add_thing(make_no_delete(thing));
// Add and transfer ownership:
app.add_thing(std::make_shared<Thing>());
}

Related

boost::signals2: connect to a slot of a diffeent class

I am trying to use the boost::signals2 functionalities in my program.
In my "Main Class" called "Solid" I have a member which I initialize inside the constructor body (so after the member initializer list) like this:
pointer_M = boost::make_shared<OtherClass>(/*parameters,...*/);
If the signal is triggered by some function I do not want to call a member of "OtherClass" (to which pointer_M points) but a member from "Solid", i.e. the class which initialized pointer_M just.
I tried the following:
boost::signals2::connection tria_signal = /*...*/.connect( boost::signals2::signal<void()>::slot_type(&Solid::call_this_function, pointer_M.get()).track(pointer_M) );
"call_this_function" is a member function of Solid. Unfortunately there are a bunch of error messages. "OtherClass" and "Solid" are not related by inheritance.
I would appreciated getting some advice how to fix my issue since I am very unexperienced with boost.
Best
But is that what I am trying to achieve possible at all?
The point is we can't tell without a clearer description. It sure sounds like a no-brainer: signals are specifically used to decouple callers and callees.
So let me just make up your "dummycode" for you. I'm going to sidestep the enormous type-overcomplication that you showed in that line:
boost::signals2::connection tria_signal =
/*...*/.connect(boost::signals2::signal<void()>::slot_type(
&Solid::call_this_function, pointer_M.get())
.track(pointer_M));
The whole idea of slots is that they generalize callables using type erasure. Just provide your callable in any compatible form and let the library deduce the arcane implementation types.
Live On Coliru
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
boost::shared_ptr<OtherClass> pointer_M;
Solid() {
pointer_M = boost::make_shared<OtherClass>(1,2,3);
auto tria_signal = pointer_M->tria.connect(
boost::bind(&Solid::call_this_function, this));
}
private:
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
Solid s;
s.pointer_M->test();
}
Prints
Solid was here
Crystal Ball: Can We Guess The Problem?
Maybe we can guess the problem: it looked like you were putting effort into tracking the lifetime of the object pointed to by pointer_M. That's not useful, since that OtherClass owns the signal in the first place, meaning that all connections are disconnected anyways when the OtherClass disappears.
Correct Lifetime Management
What you likely want is for the connection to disconnect when the lifetime of the Solid object ends, not the OtherClass. In general, I'd suggest using scoped_connection here:
Live On Coliru
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
boost::shared_ptr<OtherClass> pointer_M;
Solid() {
pointer_M = boost::make_shared<OtherClass>(1,2,3);
tria_signal = pointer_M->tria.connect(
boost::bind(&Solid::call_this_function, this));
}
private:
boost::signals2::scoped_connection tria_signal;
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
boost::shared_ptr<OtherClass> keep;
{
Solid s;
std::cout << "Testing once:" << std::endl;
s.pointer_M->test();
keep = s.pointer_M; // keep the OtherClass alive
} // destructs Solid s
std::cout << "Testing again:" << std::endl;
keep->test(); // no longer connected, due to scoped_connection
}
Prints
Testing once:
Solid was here
Testing again:
Simplify
In your case, the OtherClass is already owned by the Solid (at least it is created). It seems likely that having the shared-pointer is not necessary here at all:
Live On Coliru
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
Solid() : oc_M(1,2,3) {
tria_signal = oc_M.tria.connect(
boost::bind(&Solid::call_this_function, this));
}
void test() { oc_M.test(); }
private:
OtherClass oc_M;
boost::signals2::scoped_connection tria_signal;
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
Solid s;
s.test();
}
Because the members are destructed in reverse order of declaration, this is completely safe.
Architecture Astronauting
If you know what you're doing, and the pointer_M actually needs to be shared, then likely you want to track that pointer. You should probably be considering making Solid also enable_shared_from_this. If you want to be really "Enterprise Grade Engineer™" about it, you could perhaps do something fancy with the aliasing constructor: What is shared_ptr's aliasing constructor for?

simple singleton example in c++

I am trying to implement singleton that I have used before in PHP and Java 8, to C++. But I do face certain restrictions from the syntax and how C++ works (specifically pointers).
This is what I have tried so far:
#include "iostream"
using namespace std;
class System{
protected:
static System *obj;
public:
static System *getInstance(){
return obj;
}
void prn(){
cout<<"this works!";
}
};
int main(void){
System &sys = System::getInstance();
sys.prn();
}
while executing, I get the following error:
sameer.cpp:20:10: error: non-const lvalue reference to type 'System'
cannot bind
to a temporary of type 'System *'
System &sys = System::getInstance();
^ ~~~~~~~~~~~~~~~~~~~~~
Please help me solve this error.. as I have no idea what it means. I have checked the forum before posting, and it can be a possible duplicate of previously asked question (which I caould not find).. But I posted this because I wanted to understand the meaning of error my code generated.
Thanks for the help
In C++, references and pointers are different things. A reference behaves exactly like the original variable, whereas a pointer represents the memory address of that variable. You're getting the error because you're trying to assign a pointer-to-System to a variable of type reference-to-System, which isn't the same thing. If you really wanted to you could dereference the pointer by using the System& sys = *ptr; syntax, but in this case that's the wrong thing to do; the correct fix is to return a reference from your getInstance() function, rather than a pointer.
What's more, in C++ you can actually store the static instance variable within the getInstance() function. This is a so-called "magic static", otherwise known as a "Meyers Singleton", and since C++11 it guarantees you get thread-safe construction of the singleton object. So the final solution would be:
class System
{
private:
System() {}
public:
static System& getInstance(){
static System theInstance;
return theInstance;
}
void prn(){
cout<<"this works!";
}
};
int main()
{
System& sys = System::getInstance();
sys.prn();
}
Also, as an aside, you should use
#include <iostream>
not
#include "iostream"
to include standard library headers. And you don't need to say main(void) in C++; empty brackets signify that a function takes no arguments, so main() will do.
getInstance() returns a pointer, but you are trying to call it and bind it to a reference. If you want it to return a reference, make it return a reference.
static System &getInstance(){
return *obj;
}
#include <iostream>
using namespace std;
class System{
private:
static System *obj;
System() {}
public:
static System *getInstance()
{
if(obj == nullptr)
obj = new System();
return obj;
}
void prn(){
cout<<"this works!"<< endl;
}
};
System *System::obj;
int main(void){
System *sys = System::getInstance();
sys->prn();
}
It might be good to lazy-initialize your singleton. Also, consider making the constructor and the singleton private so you can't create an instance anywhere else.
#include <iostream>
class System
{
private:
static System *obj;
System() {}
public:
static System& getInstance(){
if (nullptr == obj)
obj = new System();
return obj;
}
void prn(){
std::cout << "this works!";
}
};
int main(void){
System& sys = System::getInstance();
sys.prn();
}

Shared pointer is working without assigning

Shared pointer is working without assign memory to Win class.
Code:
class Win
{
public:
void disp()
{
//Do something
}
};
int main()
{
std::shared_ptr<Win> sharedptr;///holds null pointer
sharedptr->disp();//// why its working
}
Why it's calling above function without assign memory to it. Could someone help me out of this?
Try to do it like this:
#include <memory>
#include <iostream>
class Win
{
public:
void disp(){std::cout << x;}
int x=5;
};
int main()
{
std::shared_ptr<Win> sharedptr;///holds null pointer
sharedptr->disp();//// why its working
}
You will not get 5. You may get anything. Like the guys in the comments said, it is undefined behaviour .

C++ How to create a std::unique_ptr from a class that takes parameters on constructor

I need to create a std::unique_ptr from a class that has a constructor that takes one parameter. I can´t find references on how to do it. Here is the code example that cannot compile:
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
class MyClass {
public:
MyClass(std::string name);
virtual ~MyClass();
private:
std::string myName;
};
MyClass::MyClass(std::string name) : myName(name) {}
MyClass::~MyClass() {}
class OtherClass {
public:
OtherClass();
virtual ~OtherClass();
void MyFunction(std::string data);
std::unique_ptr<MyClass> theClassPtr;
};
OtherClass::OtherClass() {}
OtherClass::~OtherClass() {}
void OtherClass::MyFunction(std::string data)
{
std::unique_ptr<MyClass> test(data); <---------- PROBLEM HERE!
theClassPtr = std::move(test);
}
int main()
{
OtherClass test;
test.MyFunction("This is a test");
}
The errors are related to the way I´m initializing the std::unique_ptr, pointed out in my code.
The original code and the errors can be found here.
Thanks for helping me to solve that.
You can do:
std::unique_ptr<MyClass> test(new MyClass(data));
Or if you have C++14
auto test = std::make_unique<MyClass>(data);
But:
In the provided example there is no need to create a temporary variable, you can just use the reset method of the class member:
theClassPtr.reset(new MyClass(data));
#include <memory>
...
int main()
{
std::string testString{ "Testing 1...2....3" };
auto test = std::make_unique<MyClass>( testString );
return 0;
}
It's basically an oversight. You need this:
#include <memory>
namespace std
{
template <class T, class... Args>
std::unique_ptr <T> make_unique (Args&&... args)
{
return std::unique_ptr <T> (new T (std::forward <Args> (args)...));
}
}
C++14 comes with std::make_unique. It was omitted from C++11.
Writing it yourself is easy:
namespace notstd{
template<class T,class...Args>
std::unique_ptr<T> make_unique(Args&&...args){
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
now use it like this:
auto foo = notstd::make_unique<MyClass>(string);
will make your unique ptr for you.
This pattern has a few advantages. First, it removes a new that is not paired with a delete from "user code", which makes me happy.
Second, if you call a function that takes 2 unque ptrs, ths above can avoid leaks in case of exceptions being thrown.
We put this in notstd as injecting new functions into std is illegal inder the standard (no diagnostic required).

Function calls with class members?

Before I present the code which is found at the bottom of this post I would like to talk about the issue and the fix's that I do not desire. Okay basically I've created a GUI from scratch sort of and one requirement I wanted for this was allow components to have their own click executions so if i click a button or tab etc.. It would call Component->Execute(); Well normally you would do something like a switch statement of ids and if that components ID equaled n number then it would perform this action. Well that seemed kinda dumb to me and I thought there has to be a better way. I eventually tried to incorporate a feature in JAVA where you would do like Component.AddActionListener(new ActionListener( public void execute(ActionEvent ae) { })); or something like that and I thought that this feature has to be possible in C++. I eventually came across storing void functions into a variable in which could be executed at any time and modified at any time. However I hadn't noticed an issue and that was this only worked with static functions. So below you'll see my problem. I've patched the problem by using a pointer to SomeClass however this would mean having an individual function call for every class type is there no way to store a function callback to a non-static class member without doing the below strategy? and instead doing a strategy like the commented out code?
//Main.cpp
#include <iostream> //system requires this.
#include "SomeClass.h"
void DoSomething1(void)
{
std::cout << "We Called Static DoSomething1\n";
}
void DoSomething2(void)
{
std::cout << "We Called Static DoSomething2\n";
}
int main()
{
void (*function_call2)(SomeClass*);
void (*function_call)() = DoSomething1; //This works No Problems!
function_call(); //Will Call the DoSomething1(void);
function_call = DoSomething2; //This works No Problems!
function_call(); //Will Call the DoSomething2(void);
SomeClass *some = new SomeClass(); //Create a SomeClass pointer;
function_call = SomeClass::DoSomething3; //Static SomeClass::DoSomething3();
function_call(); //Will Call the SomeClass::DoSomething3(void);
//function_call = some->DoSomething4; //Non-Static SomeClass::DoSomething4 gives an error.
//function_call(); //Not used because of error above.
function_call2 = SomeClass::DoSomething5; //Store the SomeClass::DoSomething(SomeClass* some);
function_call2(some); //Call out SomeClass::DoSomething5 which calls on SomeClass::DoSomething4's non static member.
system("pause");
return 0;
}
//SomeClass.hpp
#pragma once
#include <iostream>
class SomeClass
{
public:
SomeClass();
~SomeClass();
public:
static void DoSomething3(void);
void DoSomething4(void);
static void DoSomething5(SomeClass* some);
};
//SomeClass.cpp
#include "SomeClass.h"
SomeClass::SomeClass(void)
{
}
SomeClass::~SomeClass(void)
{
}
void SomeClass::DoSomething3(void)
{
std::cout << "We Called Static DoSomething3\n";
}
void SomeClass::DoSomething4(void)
{
std::cout << "We Called Non-Static DoSomething4\n";
}
void SomeClass::DoSomething5(SomeClass *some)
{
some->DoSomething4();
}
Secondary Fix for what I'll do not an exact answer I wanted but it meets my needs for now along with allowing additional features which would have become overly complicate had this not existed.
//Component.hpp
#pragma once
#include <iostream>
#include <windows.h>
#include <d3dx9.h>
#include <d3d9.h>
#include "Constants.hpp"
#include "ScreenState.hpp"
#include "ComponentType.hpp"
using namespace std;
class Component
{
static void EMPTY(void) { }
static void EMPTY(int i) { }
public:
Component(void)
{
callback = EMPTY;
callback2 = EMPTY;
callback_id = -1;
}
Component* SetFunction(void (*callback)())
{
this->callback = callback;
return this;
}
Component* SetFunction(void (*callback2)(int), int id)
{
this->callback_id = id;
this->callback2 = callback2;
return this;
}
void execute(void)
{
callback();
callback2(callback_id);
}
}
The syntax for pointers-to-member-functions is as follows:
struct Foo
{
void bar(int, int);
void zip(int, int);
};
Foo x;
void (Foo::*p)(int, int) = &Foo::bar; // pointer
(x.*p)(1, 2); // invocation
p = &Foo::zip;
(x.*p)(3, 4); // invocation
Mind the additional parentheses in the function invocation, which is needed to get the correct operator precedence. The member-dereference operator is .* (and there's also ->* from an instance pointer).