TIP: Click on subject to list as thread! ANSI
echo: c_echo
to: Neil Heller
from: Darin McBride
date: 2004-04-17 22:40:10
subject: Function Pointers

Hello Neil!

Replying to a message of Neil Heller to All:

 NH> Does anybody still use function pointers?

I do in perl ... but I don't use C/C++ anymore ;-)

 NH> Is there anything that function pointers can do that other construct 
 NH> cannot do?

Be more readable and more confusing at the same time?  They're largely
confusing simply because not many people use them.  At least, not
explicitly.  For example, if you use a function in a DLL somewhere, you're
using a function pointer.  But if you're not calling LoadLibrary
explicitly, you're allowing the loader to resolve everything in such a way
that your code feels like you're not using a function pointer.

Let's try an example of something that becomes really nifty with function
pointers.  If you had an application that worked with mySQL and Oracle, you
may have similar functions for both (possibly in DLLs that you load only if
needed).  So then you may have a struct like this:

struct Database {
  HDLL hdll; /* can't remember the exact type ;-> */
  error_t (*GetEmployee)(struct EmpRecord* r);
  error_t (*SaveEmployee)(struct EmpRecord* r);
};

Then you can have an initialisation function like this:

struct Database access;
error_t InitApp(...) {
  char const* db_driver = ConfigGet("database_driver");
  access.hdll = LoadLibrary(db_driver);
  /* error checking */
  /* excuse my poor win32 api's ;-> */
  INITFUNC init = ResolveFunc(access.hdll, "InitDriver");
  init(&access);

}

And then, forevermore, just call the functions through the pointers:

struct EmpRecord er;
er.empname = "Neil Heller";
access.GetEmployee(&er);
/* er is filled out from the db! */

Depending on the driver in the config, this may be an Oracle db, or a mySQL
db.  And adding support for, say, DB2 or PostgreSQL, is as easy as porting
that single DLL.

It's way faster than, say, code like this:

switch (db_driver)
{
  case DR_ORACLE: OracleGetEmployee(&er); break;
  case DR_MYSQL: MySQLGetEmployee(&er); break;
  default: abort();
}

And way easier to maintain to boot!

 NH> I read that function pointers are MUCH faster than traversing through
 NH> a  virtual table (to resolve references) for overloaded methods in
 NH> C++.

Probably depends on the vtable, and how deep the inheritance is.  The
advantage for C++, though, is that the compiler should be maintaining the
function pointers rather than you needing to maintain it.  In C++, the
above could be done simply by asking the driver to create a new C++ object
which is derived from the base class in the main executable.  The driver
would not need to do a lot of manual setting up of any structure - just
compile and go ;-)

 NH> Would anyone care to comment?

Darin

---
* Origin: Tanktalus' Tower BBS (1:250/102)
SEEN-BY: 633/267 270
@PATH: 250/102 99 10/345 106/1 2000 633/267

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.