954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Function Pointer

I got the following code out of Carrano's Walls & Mirrors. I made a few changes but have tested it and it works. I'm really confused by line 19 in the .h file. Why is it structured like "void (*FunctionType)"?

Why not (void*) FunctionType?
or void* FunctionType?

What is the significance of the parenthesis being around the *FunctionType? I've tried changing this and it only works if I leave it the way it is.

Thanks
Jake

/********************************************************************************************************************************
* @file:		BinaryTree.h
* @purpose:	Specification for the binary tree to be used for representing math equations (from Carrano's implementation
*						in Walls & Mirrors Fifth Edition)
* @author:	Frank M. Carrano 
* @date:		10/1/09
*******************************************************************************************************************************/
#ifndef BINARYTREE_H
#define BINARYTREE_H

#include "KeyedItem.h"
#include "TreeException.h"
#include "TreeNode.h"
#include <cstddef> // definition of NULL
#include <new>
#include <iostream>
using namespace std;

typedef void (*FunctionType)(TreeNode* curNode); // the function to be called during inorder traversal

/*******************************************************************************************************************************
* @class:		BinaryTree
* @purpose:	Implementation of a binary tree to be used in expressing math equations
*******************************************************************************************************************************/
class BinaryTree {
 public:
	BinaryTree();

	BinaryTree(const TreeItemType& rootItem) throw(TreeException);

	BinaryTree(const TreeItemType& rootItem, BinaryTree& leftTree, BinaryTree& rightTree) throw(TreeException);

	BinaryTree(BinaryTree& tree) throw(TreeException);

	virtual ~BinaryTree();

	virtual bool isEmpty() const;

	virtual TreeItemType getRootData() const throw(TreeException);

	virtual void setRootData(const TreeItemType& newItem) throw(TreeException);

	virtual TreeNode* attachLeft(const TreeItemType& newItem) throw(TreeException);

	virtual TreeNode* attachRight(const TreeItemType& newItem) throw(TreeException);

	virtual void attachLeftSubtree(BinaryTree& leftTree) throw(TreeException);

	virtual void attachRightSubtree(BinaryTree& rightTree) throw(TreeException);

	virtual void detachLeftSubtree(BinaryTree& leftTree) throw(TreeException);

	virtual void detachRightSubtree(BinaryTree& rightTree) throw(TreeException);

	virtual BinaryTree getLeftSubtree() const throw(TreeException);

	virtual BinaryTree getRightSubtree() const throw(TreeException);

	virtual BinaryTree& operator=(const BinaryTree& rhs) throw(TreeException);

	/********************************************************************************************************************************
	* @purpose: public method that calls the protected method inOrder, to display every node in the tree in in-order representation
	*	@param:		pointer to the function that will visit each node
	*******************************************************************************************************************************/
	virtual void inOrderTraverse(FunctionType visit); 

	virtual void preOrderTraverse(FunctionType visit);

	TreeNode *rootPtr() const;

 protected:
	BinaryTree(TreeNode *nodePtr);

	void copyTree(TreeNode *treePtr, TreeNode *& newTreePtr) const throw(TreeException);

	/********************************************************************************************************************************
	* @purpose:	Deallocates memory used by tree and deletes the tree  
	* @param:		Pointer to the tree in question
	*******************************************************************************************************************************/
	void destroyTree(TreeNode* treePtr) throw(TreeException);

	void inOrder(TreeNode *nodePtr, FunctionType visit); // this is protected because it has access to every node in the tree

	void preOrder(TreeNode *nodePtr, FunctionType visit);

	void setRootPtr(TreeNode *newRoot);

	void getChildPtrs(TreeNode *nodePtr, TreeNode *& leftChildPtr, TreeNode *& rightChildPtr) const;

	void setChildPtrs(TreeNode *nodePtr, TreeNode *leftChildPtr, TreeNode *rightChildPtr);

	TreeNode *root; // Pointer to the root of the tree
	
};

#endif

/********************************************************************************************************************************
* @file: 		BinaryTree.cpp
* @purpose:	Implementation for the binary tree to be used for representing math equations (from Carrano's implementation
*						in Walls & Mirrors Fifth Edition)
* @author:	Frank M. Carrano
* @date: 		10/2/09
*******************************************************************************************************************************/

#include "BinaryTree.h"

BinaryTree::BinaryTree() : root(NULL){
}

BinaryTree::BinaryTree(const TreeItemType& rootItem) throw(TreeException)
{
	try{
		root = new TreeNode(rootItem, NULL, NULL);
	}
	catch(bad_alloc e){
		delete root;
		throw TreeException("TreeException: constructor cannot allocate memory");
	}
}

BinaryTree::BinaryTree(const TreeItemType& rootItem, BinaryTree& leftTree, BinaryTree& rightTree) throw(TreeException){
	try{
		root = new TreeNode(rootItem, NULL, NULL);
		attachLeftSubtree(leftTree);
		attachRightSubtree(rightTree);
	}
	catch(bad_alloc e){
		delete root;
		throw TreeException("TreeException: constructor cannot allocate memory");
	}
}

BinaryTree::BinaryTree(BinaryTree& tree) throw(TreeException){
	try{
		copyTree(tree.root, root);
	}
	catch(bad_alloc e){
		destroyTree(tree.root);
		throw TreeException("TreeException: copy constructor cannot allocate memory");
	}
}

BinaryTree::BinaryTree(TreeNode *nodePtr) : root(nodePtr){
}

BinaryTree::~BinaryTree(){
	destroyTree(root);
	root = NULL;
}

bool BinaryTree::isEmpty() const{
	return(root == NULL);
}

TreeItemType BinaryTree::getRootData() const throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	return root->item;
}

void BinaryTree::setRootData(const TreeItemType& newItem) throw(TreeException){
	if(!isEmpty()){
		root->item = newItem;
	}
	else{
		try{
			root = new TreeNode(newItem, NULL, NULL);
		}
		catch(bad_alloc e){
			throw TreeException("TreeException: setRootData cannot allocate memory");
		}
	}
}

TreeNode* BinaryTree::attachLeft(const TreeItemType& newItem) throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	else if(root->leftChildPtr != NULL)
		throw TreeException("TreeException: Cannot overwrite left subtree");
	else{
		try{
			root->leftChildPtr = new TreeNode(newItem, NULL, NULL);
			return root->leftChildPtr;
		}
		catch(bad_alloc e){
			throw TreeException("TreeException: attachLeft cannot allocate memory");
		}
	}
}

TreeNode* BinaryTree::attachRight(const TreeItemType& newItem) throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	else if(root->rightChildPtr != NULL)
		throw TreeException("TreeException: Cannot overwrite right subtree");
	else{
		try{
			root->rightChildPtr = new TreeNode(newItem, NULL, NULL);
			return root->rightChildPtr;
		}
		catch(bad_alloc e){
			throw TreeException("TreeException: attachRight cannot allocate memory");
		}
	}
}

void BinaryTree::attachLeftSubtree(BinaryTree& leftTree) throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	else if(root->leftChildPtr != NULL)
		throw TreeException("TreeException: Cannot overwrite left subtree");
	else{
		root->leftChildPtr = leftTree.root;
		leftTree.root = NULL;
	}
}

void BinaryTree::attachRightSubtree(BinaryTree& rightTree) throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	else if(root->rightChildPtr != NULL)
		throw TreeException("TreeException: Cannot overwrite right subtree");
	else{
		root->rightChildPtr = rightTree.root;
		rightTree.root = NULL;
	}
}

void BinaryTree::detachLeftSubtree(BinaryTree& leftTree) throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	else{
		leftTree = BinaryTree(root->leftChildPtr);
		root->leftChildPtr = NULL;
	}
}

void BinaryTree::detachRightSubtree(BinaryTree& rightTree) throw(TreeException){
	if(isEmpty())
		throw TreeException("TreeException: Empty tree");
	else{
		rightTree = BinaryTree(root->rightChildPtr);
		root->rightChildPtr = NULL;
	}
}

BinaryTree BinaryTree::getLeftSubtree() const throw(TreeException){
	TreeNode *subTreePtr;
	if(isEmpty()){
		BinaryTree emptyTree;
		return emptyTree;
	}
	else{
		copyTree(root->leftChildPtr, subTreePtr);
		BinaryTree leftTree(subTreePtr);
		return leftTree;
	}
}

BinaryTree BinaryTree::getRightSubtree() const throw(TreeException){
	TreeNode *subTreePtr;
	if(isEmpty()){
		BinaryTree emptyTree;
		return emptyTree;
	}
	else{
		copyTree(root->rightChildPtr, subTreePtr);
		BinaryTree rightTree(subTreePtr);
		return rightTree;
	}
}

BinaryTree& BinaryTree::operator=(const BinaryTree& rhs) throw(TreeException){
	if(this != &rhs){
		destroyTree(root);
		copyTree(rhs.root, root);
	}
	return *this;
}

void BinaryTree::copyTree(TreeNode *treePtr, TreeNode *& newTreePtr) const throw(TreeException){
	if(treePtr != NULL){
		try{
			newTreePtr = new TreeNode(treePtr->item, NULL, NULL);
			copyTree(treePtr->leftChildPtr, newTreePtr->leftChildPtr);
			copyTree(treePtr->rightChildPtr, newTreePtr->rightChildPtr);
		}
		catch(bad_alloc e){
			throw TreeException("TreeException: copyTree cannot allocate memory");
		}
	}
	else
		newTreePtr = NULL;
}
	
void BinaryTree::destroyTree(TreeNode* treePtr) throw(TreeException){
	if(treePtr != NULL){
		destroyTree(treePtr->leftChildPtr);
		destroyTree(treePtr->rightChildPtr);
		delete treePtr;
		treePtr = NULL;
		if(treePtr == root) { // get rid of the root
			delete root;
			root = NULL;
		}
	}
}

TreeNode *BinaryTree::rootPtr() const {
	return root;
}

void BinaryTree::setRootPtr(TreeNode *newRoot){
	root = newRoot;
}

void BinaryTree::getChildPtrs(TreeNode *nodePtr, TreeNode *& leftPtr, TreeNode *& rightPtr) const {
	leftPtr = nodePtr->leftChildPtr;
	rightPtr = nodePtr->rightChildPtr;
}

void BinaryTree::setChildPtrs(TreeNode *nodePtr, TreeNode * leftPtr, TreeNode * rightPtr) {
	nodePtr->leftChildPtr = leftPtr;
	nodePtr->rightChildPtr = rightPtr;
}

void BinaryTree::inOrderTraverse(FunctionType visit){
	inOrder(root, visit);
}

void BinaryTree::inOrder(TreeNode* nodePtr, FunctionType visit) {
	if(nodePtr != NULL){
		inOrder(nodePtr->leftChildPtr, visit);
		visit(nodePtr);
		inOrder(nodePtr->rightChildPtr, visit);
	}
}

void BinaryTree::preOrderTraverse(FunctionType visit) {
	preOrder(root, visit);
}

void BinaryTree::preOrder(TreeNode* nodePtr, FunctionType visit) {
	if(nodePtr != NULL) {
		visit(nodePtr);
		preOrder(nodePtr->leftChildPtr, visit);
		preOrder(nodePtr->rightChildPtr, visit);
	}
}
jakethesnake86
Newbie Poster
18 posts since Oct 2008
Reputation Points: 10
Solved Threads: 0
 

>>Why not (void*) FunctionType?
or void* FunctionType?

Otherwise it won't be a function pointer

The above statement, (void*) FunctionType , or void* FunctionType?
are the same.

void (*pF) ();
means that pf is a void pointer function. If the parenthesis wasn't there
then it would be a regular function that returns a void pointer.

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

Thanks, that makes sense. My next question is how do I implement this function? I want to implement it within a different class and for the function to have access to members within its class. Is this possible?

Jake

jakethesnake86
Newbie Poster
18 posts since Oct 2008
Reputation Points: 10
Solved Threads: 0
 
The pointer point to the variable instead of copyinfg it. Any chages made to the variable by  the function will change the variable in main also
ross42111
Newbie Poster
8 posts since Sep 2009
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: