By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,007 Members | 979 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,007 IT Pros & Developers. It's quick & easy.

Creating table of const ptr to member funcs

P: n/a
Hi,

How do I create a const table of pointers to member functions?
I'm implementing a Factory pattern (or jump table). I want to
iterate through the table, calling each member function until
a non-zero index is returned. Below is my attempt, which
generates compiler errors:

namespace Reference
{
class Base
{
};
}

class My_Class
{
public:
typedef int (My_Class:: * P_ADD_REC_FUNC)
(const Reference::Base& ref);
int add_reference(const Reference::Base& ref);

private:
int add_book(const Reference::Base& ref);
int add_magazine(const Reference::Base& ref);
const P_ADD_REC_FUNC add_func_table[];
};

//[1] The following definition generates the errors.
const P_ADD_REC_FUNC My_Class::add_func_table[] =
{
add_book, add_magazine
};
static const unsigned int NUM_ADD_FUNCS =
sizeof(add_func_table) / sizeof(add_func_table[0]);

int
My_Class ::
add_book(const Reference::Base& ref)
{
// Stubbed for now.
return 0;
}

int
My_Class ::
add_magazine(const Reference::Base& ref)
{
// Stubbed for now.
return 1;
}
int
My_Class ::
add_reference(const Reference::Base& ref)
{
int id(0);
for (unsigned int i = 0;
(id == 0) && (i < NUM_ADD_FUNCS);
++i)
{
id = add_func_table[i](ref);
}
return id;
}

The error that I am getting is:
Multiple declaration for "My_Class::add_func_table"

In the past I would use a table of pointers to
static member functions. This time I thought I
would change content of the table to use pointers
to {non-static} member functions since I am referring
to the table within the same class.

So, how should I be declaring a constant table of
pointers to member functions?

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library

Jul 19 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Thomas Matthews wrote in news:3F**************@sbcglobal.net:
In the past I would use a table of pointers to
static member functions. This time I thought I
would change content of the table to use pointers
to {non-static} member functions since I am referring
to the table within the same class.

So, how should I be declaring a constant table of
pointers to member functions?


See comments inline.

namespace Reference
{
class Base
{
};
}

class My_Class
{
public:
typedef
int (My_Class:: * const P_ADD_REC_FUNC_CONST)
(Reference::Base const& ref)
;
int add_reference(const Reference::Base& ref);

private:
int add_book(Reference::Base const& ref);
int add_magazine(Reference::Base const & ref);

// Note static and new typedef
static P_ADD_REC_FUNC_CONST add_func_table[];

public:
static const unsigned int NUM_ADD_FUNCS;
};

//addition of My_Class::
My_Class::P_ADD_REC_FUNC_CONST My_Class::add_func_table[] =
{
&My_Class::add_book, &My_Class::add_magazine
};

//Now a member
unsigned int const My_Class::NUM_ADD_FUNCS =
sizeof(My_Class::add_func_table)
/
sizeof(My_Class::add_func_table[0])
;

int
My_Class ::
add_book(const Reference::Base& ref)
{
return 0;
}

int
My_Class ::
add_magazine(const Reference::Base& ref)
{
return 1;
}
int
My_Class ::
add_reference(const Reference::Base& ref)
{
int id(0);
for (unsigned int i = 0;
(id == 0) && (i < My_Class::NUM_ADD_FUNCS);
++i)
{
// Need to use ->*
id = (this->*add_func_table[i])(ref);
}
return id;
}

int main()
{
}

HTH

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #2

P: n/a
在 Sun, 02 Nov 2003 20:41:19 GMT 时, Thomas Matthews
<Th****************************@sbcglobal.net> 写了:
Hi,

How do I create a const table of pointers to member functions?
I'm implementing a Factory pattern (or jump table). I want to
iterate through the table, calling each member function until
a non-zero index is returned. Below is my attempt, which
generates compiler errors:

namespace Reference
{
class Base
{
};
}

class My_Class
{
public:
typedef int (My_Class:: * P_ADD_REC_FUNC)
(const Reference::Base& ref);
int add_reference(const Reference::Base& ref);

private:
int add_book(const Reference::Base& ref);
int add_magazine(const Reference::Base& ref);
const P_ADD_REC_FUNC add_func_table[];
};

//[1] The following definition generates the errors.
const P_ADD_REC_FUNC My_Class::add_func_table[] =
{
add_book, add_magazine
};
static const unsigned int NUM_ADD_FUNCS =
sizeof(add_func_table) / sizeof(add_func_table[0]);


i'm now find a way to do this, but i do not know is this you want,
code:
class My_Class
{
public:
typedef int (My_Class:: * P_ADD_REC_FUNC)(const Reference::Base&
ref);
int add_reference(const Reference::Base& ref);

private:
int add_book(const Reference::Base& ref);
int add_magazine(const Reference::Base& ref);
//static const P_ADD_REC_FUNC add_func_table[];
// const P_ADD_REC_FUNC add_func_table[];
//change to :
const P_ADD_REC_FUNC * add_func_table;

// and add the constructor like this:
My_Class(const P_ADD_REC_FUNC ptr_to[]) : add_func_table(ptr_to) {}
};

Jul 19 '05 #3

P: n/a
Rob Williscroft wrote:
Thomas Matthews wrote in news:3F**************@sbcglobal.net:

In the past I would use a table of pointers to
static member functions. This time I thought I
would change content of the table to use pointers
to {non-static} member functions since I am referring
to the table within the same class.

So, how should I be declaring a constant table of
pointers to member functions?

See comments inline.

namespace Reference
{
class Base
{
};
}

class My_Class
{
public:
typedef
int (My_Class:: * const P_ADD_REC_FUNC_CONST)
(Reference::Base const& ref)
;
int add_reference(const Reference::Base& ref);

private:
int add_book(Reference::Base const& ref);
int add_magazine(Reference::Base const & ref);

// Note static and new typedef
static P_ADD_REC_FUNC_CONST add_func_table[];

public:
static const unsigned int NUM_ADD_FUNCS;
};

//addition of My_Class::
My_Class::P_ADD_REC_FUNC_CONST My_Class::add_func_table[] =
{
&My_Class::add_book, &My_Class::add_magazine
};

//Now a member
unsigned int const My_Class::NUM_ADD_FUNCS =
sizeof(My_Class::add_func_table)
/
sizeof(My_Class::add_func_table[0])
;

int
My_Class ::
add_book(const Reference::Base& ref)
{
return 0;
}

int
My_Class ::
add_magazine(const Reference::Base& ref)
{
return 1;
}
int
My_Class ::
add_reference(const Reference::Base& ref)
{
int id(0);
for (unsigned int i = 0;
(id == 0) && (i < My_Class::NUM_ADD_FUNCS);
++i)
{
// Need to use ->*
id = (this->*add_func_table[i])(ref);
}
return id;
}

int main()
{
}

HTH

Rob.


Thanks for the suggestion. I've tried it and it worked.
However, I was hoping for a "const" table rather than
a static one.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 19 '05 #4

P: n/a
Thomas Matthews wrote in news:20upb.24324$0Z4.16958
@newssvr31.news.prodigy.com:
Thanks for the suggestion. I've tried it and it worked.
However, I was hoping for a "const" table rather than
a static one.

This should be possible, I put static in because of this initializer:
const P_ADD_REC_FUNC My_Class::add_func_table[] =
{
add_book, add_magazine
};


What role is "const" fulfilling. The above suggested to me that you
wanted a fixed table, since you say you don't want a static member
table, I guess you want to be able to create several My_Class
objects, all with different tables.

Perhapse a member with type std::vector< P_ADD_REC_FUNC_CONST >
would be a good place to start, or maybe:

struct My_Class
{
typedef
int (My_Class:: * const P_ADD_REC_FUNC_CONST)
(Reference::Base const& ref)
;

My_Class( P_ADD_REC_FUNC_CONST *table, std::size_t count ) :
add_fun_table( table ), add_fun_table_count( count )
{}

P_ADD_REC_FUNC_CONST * const add_func_table;
std::size_t const add_fun_table_count;

int add_book(Reference::Base const& ref);
int add_magazine(Reference::Base const & ref);
};

My_Class::P_ADD_REC_FUNC_CONST global[] = {
{ &My_Class::add_book, &My_Class::add_magazine }
};
My_Class my_instance( global, 2 );

If you could give a simple usage scenario for My_Class it might help.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #5

P: n/a
Rob Williscroft wrote:
Thomas Matthews wrote in news:20upb.24324$0Z4.16958
@newssvr31.news.prodigy.com:

Thanks for the suggestion. I've tried it and it worked.
However, I was hoping for a "const" table rather than
a static one.

This should be possible, I put static in because of this initializer:

const P_ADD_REC_FUNC My_Class::add_func_table[] =
{
add_book, add_magazine
};

What role is "const" fulfilling. The above suggested to me that you
wanted a fixed table, since you say you don't want a static member
table, I guess you want to be able to create several My_Class
objects, all with different tables.
If you could give a simple usage scenario for My_Class it might help.

Rob.


In the big picture, "My_Class" is a singleton interface to a database
of references. There are many relational tables to contain the data.
I'm using the interface to store a reference into the database (thus
the "add_*" methods) and to create references from the database.

I was hoping to have a const table of pointers to member functions
because the pointers to the functions would not change (constant
data). The quantity of pointers also doesn't change. Thus the
requirement for a constant table.

Every reference has a name and a category. The category is used
to determine which table the data is stored in. For example, the
data for a "Book" reference would be placed into the book table,
and the data for a "Magazine" reference would be placed into the
magazine table. Instead of having one public "add_" method for
each category, I'm using one public method for the base class.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 19 '05 #6

P: n/a
Thomas Matthews wrote in news:xzwpb.17123$w%4.13133
@newssvr33.news.prodigy.com:
In the big picture, "My_Class" is a singleton interface to a database
of references. There are many relational tables to contain the data.
I'm using the interface to store a reference into the database (thus
the "add_*" methods) and to create references from the database.

I was hoping to have a const table of pointers to member functions
because the pointers to the functions would not change (constant
data). The quantity of pointers also doesn't change. Thus the
requirement for a constant table.
What I don't understand here is why not a static table.

Every reference has a name and a category. The category is used
to determine which table the data is stored in. For example, the
data for a "Book" reference would be placed into the book table,
and the data for a "Magazine" reference would be placed into the
magazine table. Instead of having one public "add_" method for
each category, I'm using one public method for the base class.


You say base class so presumably you are creating a singleton
for each category (Book, Magazine). Maybe the following will help

#include <iostream>
#include <ostream>

template < typename T >
struct Basic
{
// all "base class" code here
static int const array[];
static std::size_t const array_size;

int lookup( std::size_t i )
{
// possibly do something "non-static" here ...
return array[ i % array_size ];
}
};
template < typename T > std::size_t const Basic< T >::array_size =
sizeof( Basic< T >::array ) / sizeof( int )
;
// just change (define) the tables for each specialization
struct BookTag {};

template <> int const Basic< BookTag >::array[] = { 1, 2, 3 };

struct MagazineTag {};

template <> int const Basic< MagazineTag >::array[] = { 4, 5, 6, 7 };

int main()
{
using namespace std;

Basic< BookTag > bb;
cerr << "Book size: " << bb.array_size << endl;
cerr << "Book lookup 1: " << bb.lookup( 1 ) << endl;

Basic< MagazineTag > bm;
cerr << "Magazine size: " << bm.array_size << endl;
cerr << "Magazine lookup 1: " << bm.lookup( 1 ) << endl;

}

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.