I have something like the following:
QuadMesh.h:
#include "StructureIpsim.h" // this is a struct
class QuadMesh {
public:
QuadMesh(StructureIpsim s) {//do stuff}
};
SEMPotential.h:
#include "QuadMesh.h"
#include "SpecialFuncs.h"
class SEMPotential {
public:
StructureIpsim SI;
QuadMesh mesh;
SEMPotential( //args);
};
SEMPotential::SEMPotential( //args) {
// init structure in here, need to call functions from SpecialFuncs.h to do so
// How to construct the QuadMesh object mesh? Can't put in initialization list.
}
As you can see, the QuadMesh object takes in a StructureIpsim sruct, but this struct must be initialized using several functions in the constructor of SEMPotential before being passed to the QuadMesh constructor. What's the standard way around this?
You CAN use the initializer-list. Use a helper function, which should probably be a private static member function, that accepts the relevant arguments, does the calculations, and returns a QuadMesh object. Use the initialization list to initialize the member from the return value of that helper.
class SEMPotential
{
static QuadMesh mesh_creator( /* args */ );
public:
QuadMesh mesh;
SEMPotential(/* args */) : mesh(mesh_creator(args)) {}
};
QuadMesh SEMPotential::mesh_creator( /*args*/ )
{
StructureIpsum s;
// init structure in here, calling functions from SpecialFuncs.h to do so
return QuadMesh(s);
}
As Matt McNabb points out in his comment, that helper function could be a constructor of StructureIpsum. But I present a solution that doesn't require modifying StructureIpsum or QuadMesh class definitions.
If you want to preserve the StructureIpsum instance, use the helper method trick to initialize it, and then simply use it to initialize the mesh:
SEMPotential(/* args */) : SI(ipsum_creator(args)), mesh(SI) {}
Initialization order of members is guaranteed (it's the order they appear in the class, the ordering in the initialization list has no effect).
Related
I have a functor class with an internal state and fixed output type and fixed parameters necessary for constructing the object:
class Functor
{
public:
/* constructor */
Functor(double var1, double var2 ...)
{
/* some initialization of internal variables */
}
array<double,N> operator()(double par1, ...)
{
array<double,N> output;
/* some calculations using private member functions */
return output;
}
private:
/* internal variables */
double internal_var1;
...
/* internal functions */
double internal func1(double var1, ...)
{
/* calculation */
}
...
};
This functor is instantiated in the main program using input parameters from the user.
I want to use this functor inside the member functions of other classes, which are also functors, for further calulations. One important aspect specific to this question is, that these functors use a specific signature that i cannot alter, otherwise i would just provide these functors with the result of the initial functor (i.e. the one of class Functor) as input parameters when calling them.
My idea so far (which quickly turned out to be nonsense) was to have these classes have a member that is a pointer to a class of the aforementioned functor and provide the constructor of these classes a reference to the functor:
class C1
{
public:
/* constructor */
C1(/* some parameters */, Functor* functor) // this is probably nonsense
{
/* C1 member initialization */
...
functor_ptr = functor;
}
void operator()(/* !!! fixed parameter signature here !!! */)
{
/* calulations using internal functions... */
}
private:
/* member variables and the functor class pointer*/
double internal_var1;
... etc. ...
Functor* functor_ptr;
/* member functions */
double internal_func1(double par1, ...)
{
/* use the functor */
double<array,N> tmp = (*functor_ptr)(par1, par2, ...) // more nonsense
/* more calculations */
return result;
}
double internal_func2(...)
... etc. ...
};
From what i looked up so far it seems that using a std:function call inside C1 could achieve what i'm trying to do (and i can use c++11). This post seems very similar to what i want, however, i can't figure out how to attach my functor to the std::function call as my C(ung)-fu is still rather weak. Also i couldn't figure out if it is possible to have something like std:function<array<double,N>(double,double,...> call_functor as a member of a class , which is the initialized in the constructor.
Can, and if yes how, this be done using std::function or is there a better way?
Indeed, return a function with std:function<array<double,N>(double,double,...)>, and to create it use a lambda:
std:function<array<double,N>(double,double,...)>([this](double x, double y, ...){return this->function(x, y,);};
You need to capture this of course to know on which object the method should be called.
I'm having trouble with something that seems very easy, so I must be overlooking something.
I need to construct a class that has a field that is also a class (non-POD). The class of the field has a default constructor and a "real" constructor. The thing is that I really can't construct the field in the initializer list, because in reality the constructor has a parameter that is a vector which needs a somewhat complex for loop to fill.
Here is a minimal example that reproduces the problem.
ConstructorsTest.h:
class SomeProperty {
public:
SomeProperty(int param1); //Ordinary constructor.
SomeProperty(); //Default constructor.
int param1;
};
class ConstructorsTest {
ConstructorsTest();
SomeProperty the_property;
};
ConstructorsTest.cpp:
#include "ConstructorsTest.h"
ConstructorsTest::ConstructorsTest() {
the_property(4);
}
SomeProperty::SomeProperty(int param1) : param1(param1) {}
SomeProperty::SomeProperty() : param1(0) {} //Default constructor, doesn't matter.
But this gives a compile error:
ConstructorsTest.cpp: In constructor 'ConstructorsTest::ConstructorsTest()':
ConstructorsTest.cpp:4:19: error: no match for call to '(SomeProperty) (int)'
the_property(4);
^
It gives no suggestions like it usually would of what functions could have been intended instead.
In the above example I would just initialize the_property in the initializer list, but in reality the 4 is actually a complex vector that needs to be generated first, so I really can't. Moving the_property(4) to the initializer list causes the compilation to succeed.
Other similar threads mention that the object must have a default constructor, or that it can't be const. Both requirements seem to have been met, here.
You can't initialize data member inside the constructor's body. (the_property(4); is just trying to invoke the_property as a functor.) You can only assign them like:
ConstructorsTest::ConstructorsTest() {
the_property = ...;
}
but in reality the 4 is actually a complex vector that needs to be generated first
You can add a member function which generate the necessary data, and use it to initialize the data member in member initializer list. e.g.
class ConstructorsTest {
...
static int generateData();
};
int ConstructorsTest::generateData() {
return ...;
}
ConstructorsTest::ConstructorsTest() : the_property(generateData()) {
}
You cannot initialize a variable twice.1 When your constructor has started, all member subobjects will have been constructed. If you do not provide a member initializer in the constructor, or a default member initializer in the class definition, then it will perform default initialization. Regardless of what form it takes, you can't construct it again.
Complex multi-statement initialization is best done via a lambda function:
ConstructorsTest::ConstructorsTest()
: the_property( []{ /* Do Complex Initialization */}() )
{
}
1: Well... you can, but not like that. And you really shouldn't for cases as simple as this.
I've got a class:
class Foo {
private:
Other bar;
};
and Other class:
class Other {
public:
Other(std::list<int> l, ...other parameters...);
};
Other doesn't have a default contructor and I can't add it. How can I initialize the attribute bar? I mean I need to create a list, I need to add some item and so on, so it's really difficult to use the initialization list because I need to write code to fill the list. How can I do? I think I can use a pointer instead, but I'd like to avoid dynamic allocation.
You could write a function to create the object, and use that in the initialiser list:
static Other make_bar() {
std::list<int> l;
// fill the list, do whatever else you need
return Other(l, ...);
}
Foo() : bar(make_bar()) {}
Or you could use something like boost::optional to defer initialisation without requiring dynamic allocation.
You can implement a constructor in Foo using:
Foo() : bar(std::list<int>()) {}
I am having difficulty getting my head around how to pass a class member function to a subclass (not derived).
My top level class is like this:
class CTop
{
public:
CTop();
int func1(void);
private:
CFnList* _funcList;
};
CTop::CTop():
_funcList(0)
{
_funcList = new CFnList();
_funcList->addFnPtrToList(0, &CTop::func1);
}
int CTop::func1(void)
{
// Does some stuff...
}
My function list class is like this:
class CFnList
{
public:
// Public functions
CFnList();
void addFnPtrToList(int index, int (*fn)(void));
private:
// Fn pointer list
typedef struct
{
int index;
int (*fn) (void);
}fn_list_t;
// function pointer list
QVector<fn_list_t> _fn_list;
};
So basically here I have an instance of class CTop and one of its members is a pointer to a class CFnList. CFnList pointer is instantiated in the constructor of CTop. Then I want to pass in a pointer to one of CTop's member functions to CFnList by calling the following line:
"_funcList->addFnPtrToList(0, &CTop::func1);"
I get issue (quite rightly) that addFnPtrToList does not take the parameters (int, (CTop::*)()). So the compiler knows this function is a certain member function and not just a generic (maybe static) function.
Is there a way to pass the a pointer to the member function into the sub-class? In my case I want the sub-class to be able to call this function. I am thinking I probably have to make static member functions or something, but the syntax is eluding me on how to do this.
All help / advise appreciated.
Fodder
CTop::func1 is a member function. &CTop::func1 is NOT a function pointer, it is a pointer to member (function). Those can not be mixed either in storing or calling. it is not compatible with int (*fn)(void), as the latter takes no arguments and the former requires an object that is passed as the hidden this.
For these reasons you can't have a simple but uniform facility. You either can go with simple function pointers, or pairs of PTM+object pointer, or use wrappers -- handmade or stock like boost::function fueled by boost::bind. If you have C++11 or TR1 you can use the std:: equivalents of the latter.
A declaration in the form:
int (*fn)(void)
cannot point to a member function. It can only point to a free function. Philispophically, this is because the calling conventions for member functions are different then that for free functions. Consider for example the need for a this pointer in the context of a member function call.
The syntax for declaring a pointer-to-member-function is like this:
int (CTop::*fn)(void)
There is an entire section in the C++ FAQ dedicated to member function pointers. Check it out.
You are passing the member function as if it were a regular function. That fails to include the 'this' reference to the class. In order to pass member functions, you have to be able to re-reference it from the original 'this'. Take a look at the following, instead.
typedef void (CTop::*OBJFNC)(args);
_funcList = new CFnList();
_funcList->addFnPtrToList(0, this, &CTop::func1);
void addFnPtrToList(int index, CTop* pobj, OBJFNC pfnc)
{ ... Store both ...
}
Now elsewhere you can execute it with the following.
(pobj->*pfnc)(args);
Here is the final solution, it uses a mixture of passing the instance of the object CTop and usage of template class for CFnList:
My top level class is like this (more or less the same except for the declaration of _funcList to includes the class type and to pass in the "this" to the constructor:
class CTop
{
public:
CTop();
int func1(void);
private:
CFnList<CTop>* _funcList;
};
CTop::CTop():
_funcList(0)
{
_funcList = new CFnList(this);
_funcList->addFnPtrToList(0, &CTop::func1);
}
int CTop::func1(void)
{
// Does some stuff...
}
My function list class is like this:
template<class T>
class CFnList
{
public:
// Public functions
CFnList(T *parent);
void addFnPtrToList(int index, int (T::*fn)(void));
private:
// Pointer to the parent (or owner is perhaps more correct)
T* _parent;
// Fn pointer list
typedef struct
{
int index;
int (T::*fn) (void);
}fn_list_t;
// function pointer list
QVector<fn_list_t> _fn_list;
};
// Constructor
template <class T>
CFnList<T>::CFnList(T *parent) :
_parent(parent),
_fn_list(0)
{
}
// addFnPtrToList:
template <class T>
void CFnList<T>::addFnPtrToList(int index, int (T::*fn)(void))
{
_fn_list.append((fn_list_t){index, fn});
}
So the major changes are:
1. Pass the CTop type in by using changing CFnList into a template.
2. Pass in the instance of the object CTop (so that the pointer to the function can be called) by passing "this" into the constructor and then template class stores it as a pointer to the given template type.... vio-la!...easy :o
Thanks to all who contributed :))
I am creating a bunch of C structs so i can encapsulate data to be passed over a dll c interface. The structs have many members, and I want them to have defaults, so that they can be created with only a few members specified.
As I understand it, the structs need to remain c-style, so can't contain constructors. Whats the best way to create them? I was thinking a factory?
struct Foo {
static Foo make_default ();
};
A factory is overkill. You use it when you want to create instances of a given interface, but the runtime type of the implementation isn't statically known at the site of creation.
The C-Structs can still have member functions. Problems will, however, arise if you start using virtual functions as this necessitates a virtual table somewhere in the struct's memory. Normal member functions (such as a constructor) don't actually add any size to the struct. You can then pass the struct to the DLL with no problems.
I would use a constructor class:
struct Foo { ... };
class MakeFoo
{
Foo x;
public:
MakeFoo(<Required-Members>)
{
<Initalize Required Members in x>
<Initalize Members with default values in x>
}
MakeFoo& optionalMember1(T v)
{
x.optionalMember1 = v;
}
// .. for the rest option members;
operator Foo() const
{
return x;
}
};
This allows to arbitrary set members of the struct in expression:
processFoo(MakeFoo(1,2,3).optionalMember3(5));
I have an easy idea, here is how:
Make the structure, just like you normally would, and create a simple function that initializes it:
struct Foo{...};
void Default(Foo &obj) {
// ... do the initialization here
}
If you have multiple structures, you are allowed in C++ to overload the function, so you can have many functions called 'default', each initializing its own type, for example:
struct Foo { //... };
struct Bar { //... };
void Default(Foo &obj) {...}
void Default(Bar &obj) {...}
The C++ compiler will know when to call the first or the second overload based on the parameter. The & makes obj a reference to whatever parameter you give it, so any changes made to obj will be reflected to the variable you put as parameter.
Edit:
I also have an idea for how to specify some parameters, you can do it by using default parameters. This is how it works:
For example you the following function; you can specify default values for parameters like this:
void Default (Foo &obj, int number_of_something = 0, int some_other_param = 10)
{ ... }