I have a C library with a struct like this:
struct A {
void process(){
doProcess();
};
void (*doProcess)(void);
}
Now, I have a class like
class B
{
public:
B(): a(){
a.doProcess = print();
}
void print(){
// do anything
}
private:
A a;
}
This cannot work since print is a member function and has to be called on an object of B.
Thus I tried to use the boost::bind function:
a.doProcess = boost::bind(&A::print, this)
This does not work either.
I also tried to modify the C Library and replace the function pointer definition with a boost::function definition. But then the compiler complains about not finding "" which is included in "boost/function.h".
Is there a (easy/boost) way of assigning a member function to the struct's pointer?
You simply cannot do this. Member functions have an implicit this argument that is a pointer to the object on which the function is being called. A function that does not take a B* as an argument will never manage to run on a specific B instance and a function that does not take this point as its first argument can never have the same signature as a class method. For more details on this problem and an example of a workaround read:
https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr
Pay attention to the note at the bottom of the answer on how static member functions can be used in such manner.
Pure C++ projects can use std::function & std::bind to achieve what you are asking about, but a C library used by a C++ project cannot work with these types.
I am converting my code to use unique_ptr instead of just pointers. I am trying to create a unique_ptr to a sqlite3_statement that automatically calls the function sqlite3_finalize(sqlite3_stmt *pStmt) in its custom deleter. How can I get this to work in my header file? I am completely at loss here, any help is welcome. Thanks.
With a lot of help from igleyy ( his solution gave me memory access errors when the deleter was called for some reason) I came up with this solution that seems to work and looks elegant;
Datasource.h
#pragma once
#include <sqlite\sqlite3.h>
#include <string>
#include <vector>
#include <memory>
class Datasource
{
void statementDeleter(sqlite3_stmt* object);
std::unique_ptr<sqlite3_stmt, std::function<void(sqlite3_stmt*)>> statement;
Datasource(Datasource const &);
Datasource &operator=(Datasource const &);
public:
Datasource(void);
~Datasource(void);
};
Datasource.cpp
#include "Datasource.h"
Datasource::Datasource(void) :
statement(nullptr,std::bind(&Datasource::statementDeleter,this,std::placeholders::_1))
{
}
void Datasource::statementDeleter(sqlite3_stmt * s)
{
sqlite3_finalize(s);
}
Datasource::~Datasource(void)
{
}
You could write simple lambda expression like this:
auto d = [](sqlite3_stmt* stmt) { sqlite3_finalize(stmt); };
std::unique_ptr<sqlite3_stmt, decltype(d)> statement(new sqlite3_stmt, d);
Explanation
Custom deleter is created using lambda expression and stored in variable of automatically recognized type. decltype is used to obtain type of expression (which in your case you must provide while creating unique_ptr to feed it with your custom deleter).
Edit
There are two statement variables in your Datasource class code, you need to rename one of them. You cannot initialize d and first statement variables like this. I think there is no possibility to use auto in such context, but we can use std::function. Include and replace auto d ... with std::function<void(sqlite3_stmt*)> d;. Initialize d in constructor initialization list.
Change statement to std::unique_ptr<int, decltype(d)> statement; and also initialize it in constructor initialization list.
Datesource::Datasource() :
d([](sqlite3_stmt* stmt) { sqlite3_finalize(stmt); }),
statement(new sqlite3_stmt) { /* constructor code */ }
Just define a custom deleter that frees the statement:
struct sqlite_finalizer {
void operator()(sqlite3_stmt*& s) const {
sqlite3_finalize(s);
// ... anything else.
}
};
and then make a custom typedef for it:
using sqlite3_handle = std::unique_ptr<sqlite3_stmt, sqlite_finalizer>;
sqlite3_handle handle;
I would say that unique ptr is not the way to go on this one. I say this because the stdlib already has a parallel to this for mutexes called lock_guard, you can't use lock_guard but the idea is the same. Make a class called sql_stmt_guard or something. Basically how it would work is on construction it would do the setup methods on the statement and the destructor would call sqlite3_finalize. lock_guard (or unique_lock when the situation arises) in c++ is considered idiomatic and is very useful because RAII gives you the guarantee that the unlock method will run, and for you the guarantee that your sqlite3_finalize will get called
This is another, "My code isn't working and i don't know why, " question i'm afraid. I just don't have enough knowledge of the stl to know why std::map::insert would throw an exception. If you know what cases it throws an exception, you can probably skip this wall of text and just answer. If you just desperately need some background on the issue, then have at it. I'll post my code and explain what is done, and i would be very grateful if all you with a better knowledge of the stl could explain what could be wrong with my call to insert.
I wrote an object awhile ago that i use occasionally as my go to factory object. It's main purpose is basically to take a string and store both the string and a "create new object function" pointer, so that in the end, you can call a function, pass a string, and if there is a valid registration for it, it returns a new instance of a derived object. Less talk, more code, here's what i got:
factory.h
#ifndef FACTORY_H
#define FACTORY_H
// library tools
#include <map>
#include <string>
// Simplified registration macros
#define DECLARE_DERIVED(T, base) static Factory<base>::DerivedRegister<T> reg;
#define DEFINE_DERIVED(T, base, s) Factory<base>::DerivedRegister<T> T::reg(s);
template<class base>
class Factory
{
protected:
template<class T>
static base * createT() { return new T;}
public:
typedef std::map<std::string, base*(*)()> map_type;
virtual ~Factory(){ }
static base * createInstance(const std::string & s)
{
if(!m_Map.count(s))
return nullptr;
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
}
template <class T>
struct DerivedRegister;
protected:
static map_type m_Map;
};
template<class base>
template<class T>
struct Factory<base>::DerivedRegister : public Factory<base>
{
DerivedRegister(std::string const & s)
{
m_Map.insert(std::pair<std::string, base*(*)()>(s, &createT<T>));
}
};
#endif
here's a better explanation of what it does real quick. Let's say you have a base class, class A . and then you have any number of derived classes. I make a factory object somewhere templated to A, and then either create a derived register object manually, or use the macro at the top within the derived classes declaration to create a static registry object. Then you define it in the implementation and call it's constructor, passing in a string to be used to identify the object. using the factory member createInstance you can pass in a string identifier and have a derived object returned, pointed to by an A *.
example:
A.h
class A
{
};
A.cpp
// the map for this factory template has to be defined somewhere, as it is static
Factory<A>::map_type Factory<A>::m_Map;
b.h
#include <A.h>
class B : public A
{
// anywhere in declaration of derived B
DECLARE_DERIVED(A, B)
};
b.cpp
// just somewhere in cpp file
DEFINE_DERIVED(A, B, "B")
main.cpp
int main()
{
A * ptr;
Factory<A> factory;
ptr = factory.createInstance("B");
}
This object has worked for me in the past, mostly without a hitch. Now i'm doing a project a little more complicated. I've taken a liking to the data organization/ api design involved with game engines, and i'm just trying to implement a solution of cataloging, (but not instantiated) shaders, so that you have a whole list of the shaders you've programmed, but they will not be instantiated at run-time unless needed. That aside, this question actually has nothing to do with d3d11, or at least i hope not.
So here is what's going on. I have an object that represents a graphics-shader abstract class. All the shaders you wish to write must derive from this object. The you derive from and implement it's functions differently for all your different shaders.
let's call the base object "SYNC::D3D11Shader" in namespace sync and the derived shaders "ColorShader" "LightShader" and "TextureShader". Since i do not simply want to make an std::map of instances of these shaders within the rendering object, i make a factory within the rendering object like this.
D3D11Renderer.h
class D3D11Renderer
{
// many other members...
Factory<D3D11Shader> m_ShaderFactory;
// many other member...
};
D3D11Renderer.cpp
// define this templated classes map or you'll get undefined errors
Factory<SYNC::D3D11Shader>::map_type Factory<SYNC::D3D11Shader>::m_Map;
and then in the ColorShader i use the macros like so
D3D11ColorShader.h
class D3D11ColorShader : public SYNC::D3D11Shader
{
// ...lotsa members
DECLARE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader)
// lotsa member...
};
D3D11ColorShader.cpp
// define the registery object with it's key here
DEFINE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader, "ColorShader")
this all compiles fine, and where it throws it's exception is where i first call the registryObjects constructor in D3D11ColorShader.cpp, spefically at the insert call. the exception error is this:
Unhandled exception at 0x772315de in Syncopate.exe: 0xC0000005: Access
violation reading location 0x00000004.
So in reality, the question boils down to, when does std::map::insert throw an exception and why. I just knew everyone would be asking for some background on what i'm doing. Low and behold, a giant wall of text has appeared! All i really need is a hunch.
also should i or should i not tag d3d11, because the question doesn't really pertain to it?
Here's a problem:
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
if the call to find fails (i,e. it can't find 's' in the map), then it will return m_Map.end(). Dereferencing that is a no-no.
My guess would be that this is due to the order of initialization of static variables. There is no way to control this order. So you are not guaranteed that your initialization:
Factory<A>::map_type Factory<A>::m_Map;
gets called before this initialization:
DEFINE_DERIVED(A, B, "B")
In this case the latter statement must be getting initialized first and so you map has not been allocated.
An alternative design pattern would control the initialization of the singleton factories. If you have an explicit Initialize function on each which creates the factory object then you can call this at the start of your main. E.g.
Factory.h
class Factory {
private:
static Factory* instance_;
public:
static Initialize(){instance_=new Factory;}
Factory* instance(){return instance_;}
}
Factory.cpp
static Factory* Factory::instance_ = NULL;
If you have a lot of factories you will probably want a single initialize function that initializes them all, and you will have to remember to add in the new factories as you create them.
Okay, i have actually been laboring over this error for about a day, and only now do i realize what is wrong.
problem 1:
the derived shaders header was never actually included anywhere throughout the project, and despite the fact that it never needs to be directly instantiated, it still has to be included somewhere so it can be linked and included in build.
problem 2:
interesting enough, just like combinatorial said, the initialization order was not done one after the other, but then looking over my old code, it seemed to initialize correctly before. what the difference here was, i put the factory of the derived objects within a different object then the base class. what i used to do was declare a static function and static factory within the base class so that you could instantiate any of it's registered derived classes from the base class itself. When the factory is included within the base class instead, and instantiation is done through a static function, the initialization order of all the statics seems to be constently in order ( not sure if this is always true). It runs fine now after changing this.
so now, my answer, you can get operating system exceptions like this for trying to use references to objects that were never actually included anywhere in your project. I don't have a very good knowledge of compilers or linkers to tell you why it seemed to compile fine, despite this object never being included. If someone wants to extend my answer, please.
I use MSVC++ 2010 express if that pertains to this predicament.
I have a class set up like this:
class Foo {
Foo();
private:
Bar m_bar;
}
That is the class definition in it's own header file, and now in the source file to go with it I have the constructor and I tried doing this:
Foo::Foo() {
m_bar("parameters for the Bar constructor");
}
However this doesn't work and gives me an error. I can make m_bar a pointer and then in Foo's constructor do this:
m_bar = new Bar("parameters here");
However that makes m_bar a pointer and I don't want that.
I'm not the best with C++ classes and pointers, so could something either explain a way for me to have m_bar defined in the Foo class but constructor somewhere else or if it is better to make m_bar a pointer in this situation explain why? While I would rather not make it a pointer(because I don't understand pointers extremely well), if that is the best way to do it then I would rather do it that way, but I'd still like someone to explain why that is the best way to do it(if it is).
Yes, using the initializer list syntax:
Foo::Foo() :
m_bar("parameters for the Bar constructor")
{
}
You need to use initialization lists:
Foo::Foo() :
m_bar("and you ought to check out a good C++ book :)")
{
// Book list: http://tinyurl.com/so-cxxbooks
}
If I'm understanding you right, you can use the constructor initialization list to do so.
I have some class, and in it I want to create object of another class ...
Usually I do it in header file, I just put something like:
QString RSSName;
and it works because that class has constructor that has no parameters ...
So here's my problem: how do I do that for some class(let's say ErrorOutput) that has only constructor with 1 or more parameters? I don't want to create pointer to object, I need it to be something like this:
ErrorOutput err("test");
I hope I've described the question correctly, it's little sleepy over here :P
Thanks for help :)
It's a bit hard to tell from your description what exactly you are asking for, but it sounds like "RSSName" is a member variable in your class. If I'm correct about that, initialize it in the constructor's initialization list.
class Foo
{
public:
Foo() : RSSName(someVal) { }
private:
QString RSSName;
}