Providing access to member variables between classes

This is a discussion on Providing access to member variables between classes within the C++ Programming forums, part of the General Programming Boards category; Okay, so I have this grid contained by a screen class like, and I am trying to design a member ...

  1. #1
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465

    Providing access to member variables between classes

    Okay, so I have this grid contained by a screen class like, and I am trying to design a member function to add, like, 'Thingies' to the grid.

    Code:
    class Screen
    {
    public:
    	void add(const Thingy & t);
    ...
    
    private:
    	bool ** scr;
    	int rows;
    	int cols;
    
    };
    And then a Thingy that has a chain of the coordinates it occupies like this

    Code:
    class Thingy
    {
    ...
    
    protected:
    	std::vector<COORD> v;
    
    ...
    };
    I want to flip on parts of the scr array based on the COORD's in the Thingy. I also want to derive from Thingy and make monsters and players and other wierd sorts of classes. Would it be good to just have accessors that provide access to the vectors size and COORD's at diff. indexes, or would it be better to make it public, or is there a better solution?

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    You could make Thingy a friend of Screen, although I think using friends is usually frowned upon. I would think it would be better just to have accessors to preserve encapsulation, but I'm not a design expert.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    If you don't want any other classes besides derived classes and Screen to have an interface to COORD information in Thingy, I'd make it a friend. Making public interface methods exposes whatever interface you want to give to Screen to all other users of the class. However, if the part of the goal of the Thingy class is to expose that interface, then make the member functions public even if Screen happens to be the only class to use them.

    Another choice is to separate the COORD data into a separate class that knows how to flip on or off parts of the scr array.

  4. #4
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    Since it is best not only to design a functional class hierarchy, but also design it so it cannot be misused accidentally or deliberately - friend's come in handy.

    Friend is very good for classes which manage objects and are responsible for object instantiation - such as in the case of singleton classes.

    However friend can be misused just like all of C++ can be misused. I suggest purchasing a book on common design patterns from www.amazon.com.

    It is impossible to explain how and how not to design a class hierarchy in the scope of this thread.

  5. #5
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Okay. I am trying out using friend's, but not without some errors and confusion first. Here's how I've tried laying out these classes:

    coord.h
    Code:
    #ifndef __COORD_H__
    #define __COORD_H__
    
    struct Coord
    {
    	Coord(int a, int b) : 
    	  x(a), y(b) { }
    
    	int x, y;
    };
    
    #endif
    And thingy.h
    Code:
    #ifndef __THINGY_H__
    #define __THINGY_H__
    
    
    #include <vector>
    #include "coord.h"
    #include "screen.h"
    
    class Thingy
    {
    	friend void Screen::add(const Thingy & t);
    public:
    	Thingy();
    	virtual ~Thingy();
    protected:
    	std::vector<Coord> v;
    };
    
    
    #endif
    And screen.h
    Code:
    #ifndef __SCREEN_H__
    #define __SCREEN_H__
    
    
    #include "thingy.h"
    #include <windows.h>
    
    
    class Thingy;
    class Screen
    {
    public:
    	Screen(int rows = 10, int cols = 10);
    	~Screen();
    
    	
    	void paint(HWND hwnd);
    	void add(const Thingy & t);
    
    protected:
    private:
    	bool ** scr;
    	int rows;
    	int cols;
    };
    
    #endif
    And finally screen.cpp
    Code:
    #include "screen.h"
    
    //...
    void Screen::add(const Thingy& t)
    {
    	for(std::vector<Coord>::iterator i = v.begin(); i != v.end(); ++i);
    }
    //...

    thingy.h gets an "error C2027: use of undefined type 'Screen'" pointing to the friend declaration. screen.cpp gets errors for v being undeclared. Any way I should rearrange things or declare things?

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,581
    For one, screen.h is making a forward declaration of thingy and yet you have the include in place. So, no need for the forward declaration.

    Also, I don't think you need the screen include in thingy. Replace it with a forward declaration of screen.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,304
    By the way, names that contain a double underscore or begins with an underscore followed by an uppercase letter are reserved to the implementation for any use. With that in mind, you might want to modify your header guard identifiers.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Same exact errors.

    Code:
    #ifndef i__THINGY_H__i
    #define i__THINGY_H__i
    
    
    #include <vector>
    #include "coord.h"
    
    class Screen;
    class Thingy
    {
    	friend void Screen::add(const Thingy & t);
    public:
    	Thingy();
    	virtual ~Thingy();
    protected:
    	std::vector<Coord> v;
    };
    
    
    #endif
    Code:
    #ifndef i__SCREEN_H__i
    #define i__SCREEN_H__i
    
    
    #include "thingy.h"
    #include <windows.h>
    
    
    class Screen
    {
    public:
    	Screen(int rows = 10, int cols = 10);
    	~Screen();
    
    	
    	void paint(HWND hwnd);
    	void add(const Thingy & t);
    
    protected:
    private:
    	bool ** scr;
    	int rows;
    	int cols;
    };
    
    #endif
    Last edited by Tonto; 06-19-2006 at 01:33 PM.

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,581
    Wait. My bad.

    The class granting friendship (thingy) must be defined last. And the friend class (screen) must have access to thingy name.

    So...
    Thingy includes screen.
    Screen forward declares thingy
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  10. #10
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    I get an "error C2653: 'Screen' : is not a class or namespace name" pointing to the friend declaration line in Thingy when I do that.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,304
    Perhaps something like this:

    screen.h
    Code:
    #ifndef SCREEN_H
    #define SCREEN_H
    
    class Thingy;
    
    class Screen
    {
    public:
    	void add(const Thingy & t);
    };
    
    #endif
    screen.cpp
    Code:
    #include "screen.h"
    #include "thingy.h"
    
    #include <vector>
    
    void Screen::add(const Thingy & t)
    {
    	for (std::vector<int>::const_iterator i = t.v.begin(); i != t.v.end(); ++i);
    }
    thingy.h
    Code:
    #ifndef THINGY_H
    #define THINGY_H
    
    #include <vector>
    #include "screen.h"
    
    class Thingy
    {
    public:
    	friend void Screen::add(const Thingy& t);
    private:
    	std::vector<int> v;
    };
    #endif
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Works perfectly now, thank you kindly

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 05:30 PM
  2. classes as member variables
    By Stonehambey in forum C++ Programming
    Replies: 13
    Last Post: 08-14-2008, 08:01 PM
  3. derived class can not access base class protected member?
    By George2 in forum C++ Programming
    Replies: 2
    Last Post: 10-21-2007, 07:32 PM
  4. file reading
    By gunghomiller in forum C++ Programming
    Replies: 9
    Last Post: 08-07-2007, 11:55 PM
  5. class member access denied
    By chiqui in forum C++ Programming
    Replies: 2
    Last Post: 05-27-2002, 03:02 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21