Solved

Class and Struct Problem

Posted on 1997-12-12
17
324 Views
Last Modified: 2013-12-14
can a member function be assigned to a member of  a struct.  e.g.

in c.h

struct cstruct
{
   int a;
   int b;
   void (*c) (void);      /* this is ok. pointer to a function */
}

-----------------------------------------------------
in c++.h

#include "c.h"

class  myclass

               void  memfunction();
                 .....
                  ....
                  ....
--------------------------------------------------------
in c++.C

cstruct  mystruct;

mystruct.a=5;
mystruct.b=10;
mystruct.c=myclass::memfunction; (???) /* getting bad assignment error*/
mystruct.c=ordinaryfunction; /*this will go through fine since it's                                  a normal function*/
Thanks in advance

0
Comment
Question by:valaie
  • 9
  • 3
  • 2
  • +3
17 Comments
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Answer coming
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
You ask

"can a member function be assigned to a member of a struct?"

But, I think what you are really asking is "can a member function be assigned to a function pointer?"  (the fact of whether or not the function pointer (the destination) is a member of a class or struct does not matter.)

The answer is that you can assign a member function to a pointer, but you have to declare it to have the correct type.  Actually it doesn't matter if the function is a member function or a regular function, you still have to delare the pointer to have the correct type.  The difference is that when the function is a meber function, the pointer's type must reflect that.  For example.

Alright, I'm having trouble figuring out the syntax.  Its comming though.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Okay.  I had to cheat and look it up.  Its too hard to remember where al the parenthesis go.

Say you have a class Cls and a function in it F that takes a character and returns and integer.  for example,

class Cls
{
public:
int F(char c) { return c; };
};

Now if you want to create a pointer to the function F in the class you would declare it is follows.  (I'm going to use a typedef bacause it keeps the parenthesis down somewhat.)

typedef int (Cls:: *FPtrTyp)(char);

This declares a type called "FPtrTyp", that is a pointer to function in the class "Cls" that takes a char and returns an integer.


You could use the pointer as follows.

Cls A;
Cls B;

FPtrTyp APtr = &Cls::F;

int Q1 = (A.*APtr)(1);
int Q2 = (B.*APtr)(2);

This uses the pointer with object A to initialize Q1 and with object B to initialize Q2.  If you don't "have" an object, but have a pointer to an object, you can use

Cls *ClsPtr = something();
int Q3 = *ClsPtr->*APtr)(3);

Hope this helps.
0
 

Author Comment

by:valaie
Comment Utility
Although, the question is a bit misleading, as you noticed the example clearly indicates what you said. Can a pointer to a function (which is a also a struct member) point to a member function of a class. Notice, the base type of the pointer(struct member) and the class member function is the same (it is void for both of them). Now, I don't have any problems pointing to an ordinary function with my pointer(struct member). But it is my understanding that member function is different from an ordinary function. And in order to point to a member function I have to declare a pointer with that class type. Does this make sense to you?
In other words I am looking for mor clarification.

Many thanks
Fred.
0
 

Author Comment

by:valaie
Comment Utility
Ok, remmber the pointer is defined within the struct. Not class

typedef int (Cls:: *FPtrTyp)(char);  //this will not help since I define
                                        the pointer in C not C++
struct{
int (*FPtr) (char);              /* so it has to be something like this */
}                                /* FPtr is a pointer that points to a                                         function that takes a char and                                             returns an integer */
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
I'm confused.  Where does the member part come in.  Is the function you want to point to a member function?  If so you have to do it the way I showed.  If not you do it the way you usually do.  It does not matter if the pointer to be set is a regular variable or a member of a class or struct.

something I should point out that might be the problem is that

class Cls
{
 int F1(char c);
}

int F2 (char c);

Given the two function above F1 and F2.  You can never have one pointer type that points to both of them.  Yes they both take characters and both return integers.  But one of them (F1) also takes a class as a parameter (the mysterious this pointer).  Thus they have different calling conventions and require different pointer types.  I'm not sure what your question/problem is anymore, but maybe this will clear it up.  maybe not...
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
If you still need help, try posting a little about what you are trying to do.  
0
 

Accepted Solution

by:
Rumata earned 100 total points
Comment Utility
Try doing this

mystruct.c=(void (*))(myclass::mem);

0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 

Author Comment

by:valaie
Comment Utility
Rumata,

After I tried:

mystruct.c=(void (*))(myclass::mem);

I got:

error C2643: illegal cast from pointer to member
0
 
LVL 23

Expert Comment

by:chensu
Comment Utility
You cannot cast a member function pointer to a function pointer like Rumata proposed. The problem is that there is an implicit parameter for a member function, which is the this pointer. Even if the compiler allows it to be compiled, the running result will be wrong. You have to use a pointer to member function like nietod proposed. Or, if the void memfunction() of myclass does not access any members of myclass, you can declare it as a static member function. Thus, you can use mystruct.c=myclass::memfunction;.
0
 

Expert Comment

by:Rumata
Comment Utility
Valaie,

which compiler are you using? It compiles with g++ (with an
ANSI C++ warning which does not matter).
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
It should not compile.  Even if it does, using it would be a dangerous mistake.  As Chensu and I pointed out a member function and an non-member function that look the same (same parameters and same return value) are still not the same.  The member function has one additional parameter, the this pointer.  To make things worse that parameter may be passed in a different maner than the others (it is often passed in a register rather than the stack).
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Valaie, pointers to member functions are available, but work lightly differently than pointers to regular functions.  The first difference is the the pointer's type is more complex bacause it must indicate the class the function is a member in.  the second difference is that the function is called using the pointer and a object.  Since it is a member function, it needs an object to work on.   This is what I had tried to make clear before, but failed.  Let me try again.

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Here is a class with two member functions that can be access usng the same pointer type.

class Cls
{
public:
int F(char c) { return c; };
int G(char c) { return c; };
};

Here is the pointer type to access the functions.

typedef int (Cls:: *FPtrTyp)(char);

Here is a structure to save the pointers.

struct Str
{
   Cls    *ClsPtr;
   FPtrTyp FncPtr;
   int     i;

   Str(Cls *IniCls)
   {
      ClsPtr = IniCls;
   }
   void UseF()
   {
      FncPtr = &Cls::F;
   }
   void UseG()
   {
      FncPtr = &Cls::G;
   }
   void SetI(char c)
   {
      i = (ClsPtr->*FncPtr)(c);
   }
};

Now, not knowing what you're really trying to do, I had to improvise some behavior.

When the structure is initialized it takes a pointer to an object that it will use when it calls the functions.  The pointer could be changed later and/or and object could be specified in a parameter at the time that function calls are performed.  However an object will be needed for use when calling the functions.

I provided two procedures UseF and UseG that determine which member procedure will be used the next time a member procedure is called.  This could be changed to one procedure that takes a parameter.  Actually, there are lots of posibilities, I don't know what you need.

I provided the SetI procedure that calls the member function determined by the last UseG/UseF call and by the object pointed by the ClsPtr member.  This procedure calls the member and sets the i member with the return value.

If you need more help, I think a better idea of what you are trying to do would help all of us.
0
 

Expert Comment

by:mlc121397
Comment Utility
The prototpe of a member-function isn't:
void (C*)(void), but somthing like
void (c*)(object*,...)
Memberfunctionpointers need an OBJECT!

The correct prototyping for a ptr to a member function will be:
typedef void (CLASSNAME::*aMemberFuntionPtr)(void)

Also be sure that you need an object in order to call
the function. eg:

(this->*pfn)()




0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
mlc, I'm not sure what you are suggesting with:

The prototpe of a member-function isn't:
void (C*)(void), but somthing like
void (c*)(object*,...)

If you are suggesting that a member function can be considered as taking pointer to an object in the first parameter, that is not true.  The object pointer is not necessarily passed first, last or even on the stack.  This is implementation defined.  If you are just trying make clear the fact that a member function is getting an extra (hidden) parameter, that is true.

Another way of looking at this stuff, valaie, is that a regular function pointer is a "complete" pointer.  It "completely"points to a specific procedure.  All you need to suply to use the procedure is the parameters.  A member procedure pointer, on the other hand, is only a partial pointer (Although implimentation defined, sometimes (like with virtual functions) it will not really be a pointer).  It does not exactly indicate what procedure will be called.  In addition to the parameters, you must supply an object for it to figure out what procedure to call.  

I thought that should make things clearer.  Looking back, I have no idea why I thought that.
0
 
LVL 1

Expert Comment

by:TheMadManiac
Comment Utility
method: function that is a member of a class
function: procedure not member of anything but the file it is in

you can assign pointers to methods to a function pointer, if the method is static, in which case no this pointer will be passed, but also none of the non-static members can be accesed.

ie,

class Foo
 {
public:
 static void *function(void);
 };

void (*f)(void);

main()
{
f=Foo::function;
}

this will not create any problems. It wouldn't be wise to assign a pointer to a 'C'-function to be a pointer to a non-static member of a class. This is because of the this pointer, nietod & the rest talked about.

you could on the other hand make the 'C'-function pointer a 'C++'-member pointer, ie:

void (Foo::*f)(void);

and then assign a method of Foo to f.

this way, the compiler knows it has to pass the this pointer to the function

0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now