Thread: free functions (or static members) to access private function from different class

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    free functions (or static members) to access private function from different class

    Here's my scenario ...

    I have two classes class A & B

    Code:
    // A.h
    
    Class A
    {
    private:
           void nicefoo();
           void badfoo();
    }
    Code:
    //B.H
    
    Class B
    {
    public : 
        static void firstFreeFoo();
        static void secondFreeFoo();
    }
    
    void B::firstFreeFoo()
    {
       A.niceFoo(); // I need to call nicefoo ?
    }
    
    
    void B::secondFreeFoo()
    {
       A.badFoo(); // I need to call badfoo ?
    }
    How do i achieve this...?

    my thoughts...
    1. Perhaps i can declare an instance of A inside both static functions, but then both nice&bad foo are private
    2. If i do declare two instance of foo, then i have too many class A instances, what if there are many static functions to use A? Isn't it a problem to have too many instances.
    3. Should A be a singleton?
    Last edited by csonx_p; 07-25-2008 at 04:19 AM.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You do need an instance to call non-static member functions on. If B for some reason needs to call private methods of A, then A could declare B as a friend class.

    However, design-wise you can't get much meaningful help on class interactions if you don't tell what these classes and functions actually represent.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by anon View Post
    You do need an instance to call non-static member functions on. If B for some reason needs to call private methods of A, then A could declare B as a friend class.

    However, design-wise you can't get much meaningful help on class interactions if you don't tell what these classes and functions actually represent.
    After making B a friend to A, how do i access A's private members? Do i still need an instance of A in B functions? I get an error saying identifier not found (nicefoo) if i don't say A.nicefoo()

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Unless you are going to tell what you are trying to achieve any advice is as good as any other. Make nicefoo and badfoo free functions (perhaps restricted to the file B is implemented in). Or make them methods of B instead (what is the purpose of them being private non-static members of A if they apparently won't use any data from A anyway). Etc.

    Do i still need an instance of A in B functions?
    Yes, technically you either need an instance of A, or they would have to be static member functions. Which you choose (if not one listed above) naturally depends on what they are all for.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Classes are blueprints - objects that do not yet exist.
    The whole idea behind classes is that they "are" something - an object that exists and its functions and member data are unique to that perticular instance.
    So therefore, you cannot call functions or use stuff in a blueprint.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by anon View Post
    Unless you are going to tell what you are trying to achieve any advice is as good as any other. Make nicefoo and badfoo free functions (perhaps restricted to the file B is implemented in). Or make them methods of B instead (what is the purpose of them being private non-static members of A if they apparently won't use any data from A anyway). Etc.


    Yes, technically you either need an instance of A, or they would have to be static member functions. Which you choose (if not one listed above) naturally depends on what they are all for.
    Code:
    // Class menu
    #ifndef MENU_H
    #define MENU_H
    
    #include <iostream>
    #include <string>
    #include "MenuItem.h"
    
    class Menu 
    {
    private:
    	struct MenuNode {
    		MenuNode *next;
    		MenuItem *item;
    	};
    
    	MenuNode *head;
    	MenuNode *tail;
    
    public:
    	Menu();
    	~Menu();
    
    	void addMenu(std::string s, char c, MenuFunc f);
    	void choose(MenuContext &ctxt);
    
    	// Menu operation functions
    	static void Exit(MenuContext &ctxt);
    	static void AddCarOption(MenuContext &ctxt);
    	static void EditCarOption(MenuContext &ctxt);
    	static void ListCarsOption(MenuContext &ctxt);
    	static void ReadFileOption(MenuContext &ctxt);
    	static void SearchCarOption(MenuContext &ctxt);
    	static void UpdateCarOption(MenuContext &ctxt);
    	static void DeleteCarOption(MenuContext &ctxt);
    	static void TitleDescription(MenuContext &ctxt);
    };
    Code:
    // Class Fleet : Handles all Fleet functions to process the fleet data
    #ifndef FLEET_H
    #define FLEET_H
    
    #pragma once
    
    #include <vector>
    #include "Car.h"
    #include "Menu.h"
    
    #define MAX_PATH 50
    
    // Class Fleet : Acts as a Main controller 
    using namespace std;
    
    typedef struct { 
    		string make; 
    		string model;
    	} CAR_MAKE;
    
    class Fleet
    {
    public:
    
    	friend class Menu;
    
    	Fleet();
    	void RunFleet();
    
    private:
    
    	typedef vector<Car> CarFleet;
    	typedef CarFleet::iterator FleetIterator;
    
    	CarFleet getFleet();
    
    	void SortAlpha();
    	void AddNewCar();
    	void DeleteCar();
    	void ShowFleetList();
    	void CreateContract();
    	void UpdateFleetFile();
    	void ReadFleetFromFile();
    	void EditFleetContract();
    	FleetIterator find(FleetIterator&);
    	Car& matchRightCar(FleetIterator iter);
    
    private:
    	CarFleet fleet; 
    };
    
    #endif
    Menu use fleet functions which are private...
    i.e.
    Code:
    // Menu Function : To add new car to fleet list
    void Menu::AddCarOption(MenuContext &ctxt)
    {
    	Fleet operate;
    	
    	Clrscr();
    
    	cout << "\t\t\t\t&#201;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#187;\n";
    	cout << "\t\t\t\t&#186;    NEW CAR    &#186;\n";
    	cout << "\t\t\t\t&#200;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#205;&#188;\n";
    	
     
    	operate.AddNewCar(); //HERE <---
    
    	Pause();
    }
    At the same time, Fleet use Menu functions to generate a list of Menu

    i.e.
    Code:
    void Fleet::RunFleet()
    {
    	Menu m;
    	MenuContext ctxt;
    
    	// Add menu items to the List
    	Clrscr();
    	m.addMenu("Description of Program", '1', TitleDescription);
    	m.addMenu("Read Fleet from File", '2', ReadFileOption);
    	m.addMenu("Display List of cars", '3', ListCarsOption);
    	m.addMenu("Search Car: [Model+Make]", '4', SearchCarOption);
    	m.addMenu("Add new car details", '5', UpdateCarOption);
    	m.addMenu("Save Fleet File", '6', AddCarOption);
    	m.addMenu("Edit Fleet", '7', EditCarOption);
    	m.addMenu("Delete Car", '8', DeleteCarOption);
    	m.addMenu("Main Menu", '9', Exit); 
    
    	while (!ctxt.fquit) {
    		m.choose(ctxt);
    	}
    }
    All these functions from TitleDescription to Exit are static members of Menu... Compiler complains that Fleet can't see them, even if i say m.Exit ??

    SO! Both functions uses each others member functions, but am not wining in accessing static members from Menu in Fleet
    Last edited by csonx_p; 07-25-2008 at 06:32 AM.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I see not why the Fleet should not allow stuff to be added to the fleet. It is a fleet, after all. So they should be public, if you ask me.
    Static members are not part of the class instance and must therefore be accessed via the class's namespace, say: Menu::Exit.
    Note that it's not good to have static members unless you have special reasons.
    I'm guessing you want to use function pointer to the class members and it doesn't work, so you made them static. Am I right?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    I'm guessing you want to use function pointer to the class members and it doesn't work, so you made them static. Am I right?
    Yes, and am getting this error if non-static...

    Code:
    : error C3867: 'Menu::TitleDescription': function call missing argument list; use '&Menu::TitleDescription' to create a pointer to member

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, because you're doing it wrong.
    Instead of doing &TitleDescription, instead type &Menu::TitleDescription as it says.
    Then also make the functions take an extra argument, which will be the address of the class (the instance of the Menu class, typically you'll want to pass the this pointer in this case).

    The type of the function pointer should be
    void (Menu::*)(MenuContext&);

    To call the function, you could do
    Menu* pThis; // Address of the class instance
    void (Menu::* pFunction)(MenuContext&); // Function pointer
    (pThis->*pFunction)(...);
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    Yes, because you're doing it wrong.
    Instead of doing &TitleDescription, instead type &Menu::TitleDescription as it says.
    Then also make the functions take an extra argument, which will be the address of the class (the instance of the Menu class, typically you'll want to pass the this pointer in this case).

    The type of the function pointer should be
    void (Menu::*)(MenuContext&);

    To call the function, you could do
    Menu* pThis; // Address of the class instance
    void (Menu::* pFunction)(MenuContext&); // Function pointer
    (pThis->*pFunction)(...);
    This is currently the class which handles the typedef of the function pointer
    Code:
    #ifndef MENUCONTEXT_H
    #define MENUCONTEXT_H
    
    // Class MenuContext
    class MenuContext 
    {
    public:
    	bool fquit;
    	MenuContext() : fquit(false) {}
    	~MenuContext() {};
    };
    typedef void (*MenuFunc)(MenuContext &ctxt);
    
    #endif
    should i change the above to
    Code:
    typedef void (*MenuFunc) (Menu::* pFunction)(MenuContext&); // Function pointer

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by Elysia View Post
    Yes, because you're doing it wrong.
    Instead of doing &TitleDescription, instead type &Menu::TitleDescription as it says.
    Then also make the functions take an extra argument, which will be the address of the class (the instance of the Menu class, typically you'll want to pass the this pointer in this case).

    The type of the function pointer should be
    void (Menu::*)(MenuContext&);

    To call the function, you could do
    Menu* pThis; // Address of the class instance
    void (Menu::* pFunction)(MenuContext&); // Function pointer
    (pThis->*pFunction)(...);
    Manage to solve it as you suggested... Without using mencontext though
    Code:
    		itemIterator iter=items.begin();
    
    		// Find the matching Menu choice
    		for (; iter != items.end(); ++iter) 
    		{
    			if (iter->choice == c) 
    			{
    				Func f = iter->func;
    				(this->*f)();
    				return;
    			}
    		}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 20
    Last Post: 01-26-2009, 01:33 AM
  2. How properly inherit from template?
    By 6tr6tr in forum C++ Programming
    Replies: 118
    Last Post: 04-25-2008, 04:30 AM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. Private Static class members
    By earth_angel in forum C++ Programming
    Replies: 13
    Last Post: 08-29-2005, 06:37 AM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM