[comp.lang.c++] static member functions

oneel@heawk1.gsfc.nasa.gov ( Bruce Oneel ) (05/20/91)

This may be a silly question, but, why is the static needed on member
function a in class test?  I've found this in both g++ as well as
Borland's C++ and I don't understand why from reading the ARM...  The
error message produced when I remove static from the 4th line in g++
is
testcc: In function int main():
test.cc:25: bad argument 0 for functino `test1::b (auto long int
(*)(int))' (type was long in (class test::*)(int))

Thanks in advance for all of your help!!

bruce

This compiles ok.
=================CUT HERE ==================

class test
{
 public:
  static long a (int);
};

class test1
{
 public:
  long b (long (*)(int));
};

long test::a(int i)
{
  return i;
}


test Atest;
test1 Btest;

int main(void)
{

  Btest.b(Atest.a);
  return 0;
}
=================CUT HERE ==================


This doesn't...
=================CUT HERE ==================
class test
{
 public:
  long a (int);
};

class test1
{
 public:
  long b (long (*)(int));
};

long test::a(int i)
{
  return i;
}


test Atest;
test1 Btest;

int main(void)
{

  Btest.b(Atest.a);
  return 0;
}
==============CUT HERE==================

Thanks!!!


bruce
--
Bruce O'Neel              oneel@heasfs.gsfc.nasa.gov
NASA/GSFC/STX/Code 664

davew@panache.cs.umd.edu (David G. Wonnacott) (05/21/91)

In article <ONEEL.91May20101158@heawk1.gsfc.nasa.gov> oneel@heawk1.gsfc.nasa.gov ( Bruce Oneel ) writes:
>This may be a silly question, but, why is the static needed on member
>function a in class test? 
>
>
>This compiles ok.
>=================CUT HERE ==================
>
>class test
>{
> public:
>  static long a (int);
>};
>
>class test1
>{
> public:
>  long b (long (*)(int));
>};
>
>long test::a(int i)
>{
>  return i;
>}
>
>
>test Atest;
>test1 Btest;
>
>int main(void)
>{
>
>  Btest.b(Atest.a);
>  return 0;
>}
>=================CUT HERE ==================
>
>
>This doesn't...

 (code repeated without "static")

>
>bruce


The type of a non-static member function is not the same as the type
of a "normal" function.  A pointer to non-static member function of
class test, that takes an int argument and returns void, has type

	void (test::*)(int)

and is dereferenced with the .* or ->* operator:

   	(Atest.*fp)(3);

A pointer to a similar function that is not a member of class test has
type

	void (*)(int)

and is dereferenced with the traditional * operator:

	(*fp)(5);


The reason that "static" is needed in your code above is: "a pointer
to a static member ... is treated as an ordinary pointer" (ARM p. 25)
This makes a call thru a pointer to a static member function
indistinguishable from a call thru a regular function, which is
consistent with the lack of an object to serve as "this" in these
cases.


The following code demonstrates the declaration and use of pointers to
functions, member functions, and static member functions:

#include <stream.h>

class test
{
 public:
  void a1 (int);
  static void a2 (int);
};

void a3(int i);


typedef void (*f_ptr)(int);		    // pointer to function
typedef void (test::*mf_ptr)(int);	    // ptr to test member function

class test1
{
 public:
  void b1(mf_ptr);
  void b2(f_ptr);
};

test Atest;
test1 Btest;


void test1::b1(mf_ptr fp)
{
    (Atest.*fp)(3);
}

void test1::b2(f_ptr fp)
{
    (*fp)(5);
}


int main(void)
{
  cout << "Btest.b1(Atest.a1);\n";
  Btest.b1(Atest.a1);

  cout << "\nBtest.b2(a3);\n";
  Btest.b2(a3);

  cout << "\nBtest.b2(Atest.a2);\n";
  Btest.b2(Atest.a2);

  cout << "\nBtest.b2(test::a2);\n";
  Btest.b2(test::a2);

  return 0;
}


void test::a1(int i)
{
  cout << "test::a1 got " << i << "\n";
}

void test::a2(int i)
{
  cout << "test::a2 got " << i << "\n";
}

void a3(int i)
{
  cout << "a3 got " << i << "\n";
}
--
David Wonnacott
davew@tove.cs.umd.edu

     Although the moon is smaller than the earth, it is further away.