473,668 Members | 2,759 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Functor Question - part II

Apologies for the length of this message, but I'm having problems
getting an alternate function to be executed via a functor
implementation.

I have two classes (BkgLand and BkgWater) that comprise a portion of a
much larger simulation. These classes exist in separate libraries
although the library that class BkgWater is in links in the library
containing the BkgLand class (sounds confusing I know). In the
simulation architecture that I'm using to implement these classes, the
Land based classes will be instantiated by default and the functors
will be registered for those classes. If the Water class objects are
present within the system I build (i.e. I've built an executable
containing the Water class), then the Water based classes will be
instantiated after the Land classes and those water functors are then
registered (and should take precedence).

When I test the simulation for a Land configuration I see that the
Land based functors execute just fine (and the Water objects aren't
present). When I configure the simulation for a 'Water case', I see
the message that the Land functors are being registered and then the
Water functors are being registered (as I expected), but when the
'Call_m' function is called (from the "Land" side of the simulation),
I get a segmentation fault. I checked for null pointers, but didn't
see evidence of that.

I don't know if :
- I've declared the funcTable arrays correctly and in the
appropriate sections of code (I had several compilation errors prior
to using the approach outlined below).
- There are some kind of scope issues
- Something between the two libraries is missing to allow the
land based side of the program to interpret the registered water
functions.

It almost seems as if the program doesn't know which function really
should be getting used (specFunc_0 from land or from water) when the
Call_m function is invoked for the water configuration.

Something to note, the programming guidelines I was given constrained
me to not compiling / linking libWater.so with the land based code,
only vice-versa is allowed.

Any suggestions would be greatly appreciated. Alf was already a big
help in an earlier question I posted on a related topic. Please see
the following code snippets. I will be glad to provide more
information if needed.

Danny
#ifndef TFUNCTOR_H
#define TFUNCTOR_H

#include "my_config. h"
#include "Struct1.h"
#include "Struct2.h"

BEGIN_MY_NAMESP ACE

class TFunctor
{
public:

virtual void Call_m(STRUCT1* , STRUCT2*)=0;
};
END_MY_NAMESPAC E

#endif //TFUNCTOR_H

#ifndef SPECFUNCTOR_H
#define SPECFUNCTOR_H

#include "my_config. h"
#include "TFunctor.h "

BEGIN_MY_NAMESP ACE

template <class TClassclass TSpecificFuncto r : public TFunctor
{
public:

// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
TSpecificFuncto r( TClass* _pt2Object, void(TClass::*t fpt)
(STRUCT1*, STRUCT2*) )
{ pt2Object = _pt2Object; fpt = tfpt; };

// override function "call" in base class
virtual void Call_m(STRUCT1* bkgnd, STRUCT2* geo)
{ (*pt2Object.*fp t) (bkgnd, geo);

private:
void (TClass::*fpt) (STRUCT1*, STRUCT2*);
};
END_MY_NAMESPAC E

#endif //SPECFUNCTOR_H

#ifndef BKGLAND_H
#define BKGLAND_H

#include "my_config. h"

#include "Struct1.h"
#include "Struct2.h"

BEGIN_MY_NAMESP ACE

class BkgLand
{
public:

// Constructor/Destructor
BkgLand() {};
virtual ~BkgLand() {};

void Initialize();
void Update();

TFunctor::TFunc tor *funcTable[];
};

END_MY_NAMESPAC E

#endif // BKGLAND_H
BKGLAND.cpp Code (compiled in library LIBGround.so):

#include "BkgLand.h"
#Include "SpecFuncto r.h"
#include "LandScats. h"

void BkgLand::Initia lize( )

cout << "REGISTER LAND FUNCTIONS" << endl;

// init_test function is a public member of the LandScats class
LandScats objLand;
TSpecificFuncto r<LandScatsspec Func_0(&objLand ,
&LandScats::ini t_test);
TFunctor::TFunc tor *funcTable[] = { &specFunc_0 };
}

void BkgLand::Update ()
{
//geom* and bkgndscat* are provided to this class via accessor
methods.

// Call appropriate registered function (can be land or water
based)
funcTable[0]->Call_m(bkgndsc at, geom);
}

BKGWATER.cpp Code (compiled in a separate library, LIBWater.so, but
LIBGround is linked in when this library is built):

#include "BkgWater.h "
#include "TFunctor.h "
#include "SpecFuncto r.h"
#include "WaterScats .h"

void BkgWater::Initi alize()
{
cout << "REGISTER WATER FUNCTIONS" << endl;

// init_test function is a public member of the WaterScats
class
WaterScats objWater;
TSpecificFuncto r<WaterScatsspe cFunc_0( &objWater,
&WaterScats::in it_test);
TFunctor::TFunc tor *funcTable[] = { &specFunc_0 };
}

#ifndef BKGWATER_H
#define BKGWATER_H

#include "Tfunctor.h "

BEGIN_MY_NAMESP ACE
class BkgWater
{
BkgWater();
virtual ~BkgWater();

public:
virtual void Initialize();
TFunctor::TFunc tor *funcTable[];

}
END_MY_NAMESPAC E
#endif // BKGWATER_H

Nov 11 '07 #1
4 1376
On Nov 11, 6:38 pm, BSand0...@msn.c om wrote:

[...]
There are several obvious errors in the code you posted. But
it's not the actual code, since it won't compile. (And you
really should strip out the namespace management macros junk
before posting. It may be necessary in your environment, but it
just causes confusion here.)
class TFunctor
{
public:
virtual void Call_m(STRUCT1* , STRUCT2*)=0;
};
template <class TClassclass TSpecificFuncto r : public TFunctor
{
public:

// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
TSpecificFuncto r( TClass* _pt2Object, void(TClass::*t fpt)
(STRUCT1*, STRUCT2*) )
{ pt2Object = _pt2Object; fpt = tfpt; };
Where is pt2Object declared? What is its type (presumably
TClass*, but it could be a base class pointer, or even void*)?
// override function "call" in base class
virtual void Call_m(STRUCT1* bkgnd, STRUCT2* geo)
{ (*pt2Object.*fp t) (bkgnd, geo);
If pt2Object is a pointer, this statement isn't legal, and
shouldn't compile. If pt2Object is a TClass*, then what you
probably want is:

{ (pt2Object->*fpt)( bkgnd, geo ) ; }

Putting an additional parentheses around *pt2Object would also
work.
private:
void (TClass::*fpt) (STRUCT1*, STRUCT2*);
};
class BkgLand
{
public:

// Constructor/Destructor
BkgLand() {};
virtual ~BkgLand() {};

void Initialize();
void Update();
TFunctor::TFunc tor *funcTable[];
Why TFunctor::TFunc tor, instead of just TFunctor? I think it's
legal (because of type injection), but it is very confusing to
the reader, and I seem to recall encountering some compilers
which didn't accept it. (On seeing the name TFunctor after
TFunctor::, the compiler treated it as the "name" of a
constructor).

This won't compile anyway, of course, since you have to specify
the dimensions of a (non-static) member table.
};
void BkgLand::Initia lize( )
cout << "REGISTER LAND FUNCTIONS" << endl;
// init_test function is a public member of the LandScats class
LandScats objLand;
TSpecificFuncto r<LandScatsspec Func_0(&objLand ,
&LandScats::ini t_test);
TFunctor::TFunc tor *funcTable[] = { &specFunc_0 };
The above statement is a no-op. You define a local table of
pointers to TFunctor (again, same comment as above concerning
the name), with a dimension of 1, and initialize it with the
address of a local variable. You then immeately leave the
function, causing both the table and the local variable to
cease to exist. (Of course, the TSpecificFuncto r instance
contains a pointer to still another local variable, and so
wouldn't be usable outside of the function anyway.
}
void BkgLand::Update ()
{
//geom* and bkgndscat* are provided to this class via accessor
methods.
// Call appropriate registered function (can be land or water
based)
funcTable[0]->Call_m(bkgndsc at, geom);
Here, of course, you use the funcTable variable of the object.
Since you've never initialized the contents of the table,
however, you've got totally undefined behavior.
}
BKGWATER.cpp Code (compiled in a separate library,
LIBWater.so, but LIBGround is linked in when this library is
built):
Has all of the problems of BKGLAND.cpp, so I won't bother
commenting.

Since your code won't compile, it's rather irrelevant to talk
about what it does on execution. If you want help with a
specific symptom, then you really should post the actual code
which causes that symptom. Otherwise, we really can't help you
much.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 12 '07 #2
On Mon, 12 Nov 2007 09:00:17 +0000, James Kanze wrote:
On Nov 11, 6:38 pm, BSand0...@msn.c om wrote:
[snip]
> // override function "call" in base class virtual void
Call_m(STRUCT1* bkgnd, STRUCT2* geo) { (*pt2Object.*fp t) (bkgnd,
geo);

If pt2Object is a pointer, this statement isn't legal, and shouldn't
compile. If pt2Object is a TClass*, then what you probably want is:

{ (pt2Object->*fpt)( bkgnd, geo ) ; }

Putting an additional parentheses around *pt2Object would also work.
Surprisingly it should compile - .* and ->* operators have lower
precedence than dereference operator (*). But of course relying on this
makes no sense and operator ->* is appropriate here. I remember this
precedence only because it's so counter-intuitive.

[snip]
> // Call appropriate registered function (can be land or water
based)
funcTable[0]->Call_m(bkgndsc at, geom);

Here, of course, you use the funcTable variable of the object. Since
you've never initialized the contents of the table, however, you've got
totally undefined behavior.
I couldn't see its definition so I would expect linker error.
--
Tadeusz B. Kopec (tk****@NOSPAMP LEASElife.pl)
When in panic, fear and doubt,
Drink in barrels, eat, and shout.
Nov 12 '07 #3
On Nov 12, 10:18 pm, "Tadeusz B. Kopec" <tko...@NOSPAMP LEASElife.pl>
wrote:
On Mon, 12 Nov 2007 09:00:17 +0000, James Kanze wrote:
On Nov 11, 6:38 pm, BSand0...@msn.c om wrote:
[snip]
// override function "call" in base class virtual void
Call_m(STRUCT1* bkgnd, STRUCT2* geo) { (*pt2Object.*fp t) (bkgnd,
geo);
If pt2Object is a pointer, this statement isn't legal, and shouldn't
compile. If pt2Object is a TClass*, then what you probably want is:
{ (pt2Object->*fpt)( bkgnd, geo ) ; }
Putting an additional parentheses around *pt2Object would also work.
Surprisingly it should compile - .* and ->* operators have lower
precedence than dereference operator (*). But of course relying on this
makes no sense and operator ->* is appropriate here. I remember this
precedence only because it's so counter-intuitive.
You're right.

I'll admit that I don't bother memorizing anything but the
"obvious" precedences: */ before +-, unary before binary, and
post-fix before pre-fix, and logical operators and comparisons
after everything else. Interestingly enough, this case is
actually covered by those rules: .* is a binary operator. But
I'm so used to the binding of . and -that it didn't occur to
that .* and ->* would be different. (It's one of those things
that are obvious... once they've been pointed out to you.)
[snip]
// Call appropriate registered function (can be land or water
based)
funcTable[0]->Call_m(bkgndsc at, geom);
Here, of course, you use the funcTable variable of the object. Since
you've never initialized the contents of the table, however, you've got
totally undefined behavior.
I couldn't see its definition so I would expect linker error.
It was defined as a non-static member of the class. The problem
is that he didn't give a dimension, so the definition wouldn't
be legal, and the compiler should have complained.

If it were a static member, of course, then the declaration in
the class is not a definition, so the type doesn't have to be
complete, and he can use a simple []. But then, as you say, he
needs a definition somewhere or the linker should complain.

The real problem, of course, is that he's not posting the real
code (at least judging from the symptoms he described).

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 13 '07 #4
On Tue, 13 Nov 2007 09:45:13 +0000, James Kanze wrote:
[snip]
It was defined as a non-static member of the class. The problem is that
he didn't give a dimension, so the definition wouldn't be legal, and the
compiler should have complained.
It must this funny property of human brain - I saw what I thought it
should be not what it really was. I saw no dimension, I knew definition
needs a dimension so I saw 'static' there. :-)
BTW: my gcc 4.1.3 needs -pedantic to complain about zero-sized arrays.
--
Tadeusz B. Kopec (tk****@NOSPAMP LEASElife.pl)
Any excuse will serve a tyrant.
-- Aesop
Nov 13 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
5092
by: Sean | last post by:
#include <iostream> #include <algorithm> struct functor { ~functor() {std::cout << 'D';} void operator()(int a) {std::cout << a;} }; int main() { int a = {1,2,3,4,5}; functor f;
6
5924
by: Gert Van den Eynde | last post by:
Hi all, I'm struggling a bit with Functors generated for an ABC. This is the functor code: class Functor{ public: virtual double operator(double x)=0 }
3
2160
by: CoolPint | last post by:
I have implemented a generic priority queue below and tested it works fine, but I have one small problem I cannot understand. I have type parameter F which determines the priority so that users can instantiate in the following ways PQueue<int> pq1; PQueue<int, Functor> pq2; // where Functor is a name of user-defined class I also added another constructor to accept a function pointer so that
8
2696
by: Amit | last post by:
Hello all. If I want to use an object both as a Functor and also, if I pass a function pointer, how can it be done ? For instance, I have something like this template< typename Iter, typename Predicate> class MyOperation: public std::binary_function<Iter, Iter,bool> { public: bool operator() (const Iter &val1, const Itr &val2) const {
8
1977
by: daniel.w.gelder | last post by:
Hello, I have been trying to write a functor template for a week now and I'm just having tons of trouble because I don't understand an issue that I guess is pretty basic to this task. functor<bool (long, long)> myFunctor; myFunctor = AFunctionOfThatPrototype; To get that much is elementary because the template can just store a (bool)(long,long) as a member variable in functor<T>. Here is the problem:
4
2900
by: daniel.w.gelder | last post by:
I wrote a template class that takes a function prototype and lets you store and call a C-level function, like this: inline string SampleFunction(int, bool) {..} functor<string (int, bool)> myFunctor = SampleFunction; string result = myFunctor(7, true); Works great thanks to the help from this group. Here's the guts so far for two-arity:
12
1951
by: aaragon | last post by:
Hi everyone, I'm trying to provide some external functionality to a class through a functor object defined by the user. The concept is as follows: template <class Functor> class ClassA { ... double evaluate(){
2
2512
by: Lionel B | last post by:
I have a function which takes a functor argument. I which to call it for a functor which is actually a class member; this works fine, using the mem_fun_ref and bind1st functions (see listing 1 below). Or, rather, it works fine as long as my member functor is const. The problem comes when I wish to use it for a *non*-const functor (see listing 2 below): *** Start listing 1 *************************************************** // test1.cpp
5
2525
by: Fei Liu | last post by:
Hello, I have a situation where I need to design a library for multi-thread application, each thread does some work in a client supplied std::ptr_fun(free_function) or a functor. Now since it's a multi-threaded application, naturally I want the call back functor to be created on a per thread basis. Suppose my thread is so defined template <typename servlet_type>
2
2285
by: aaragon | last post by:
Hi guys, Is there a way to return a functor from a recursive call that takes different paths? Let's say that I have a tree structure like: root | first child ---- nextSibling ----nextSibling ----nextSibling ---->0 | |
0
8462
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8893
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8797
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8583
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7401
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5681
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4205
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4380
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2023
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.