views:

79

answers:

2

Earlier, I asked a question on how to call a static member's member functions so as to initialize it before making actual use of the static object. Then, I realized that I was perhaps making use of the static member in a wrong way, which led to this question:

Given a particular class, MyClass, in how many ways can we design our code so that MyClass can gain access to the member functions of another class, YourClass? [N.B. Assume a generic situation where MyClass is declared in MyClass.h and defined in MyClass.cpp, and similarly for YourClass.]

I can think of a few, but being far from an expert, I guess you could name several others:

Containment: This can come in several 'flavors', with direct containment of a YourClass object being one option, while containing a pointer or reference to the object being another option:

class MyClass
{
public:
  // Some MyClass members...
private:
  YourClass instance;  // or YourClass* instance / YourClass& instance;
  // Some other MyClass members...
};

a) Of course, direct containment is convenient, but I can think of one immediate drawback: if YourClass is a bit hefty in terms of memory requirement, and you have several MyClass instances (as in my linked question), containing the object directly will be out of the question. Besides, the has-a relationship does not always make sense.

b) Having a pointer or a reference to the object might make better sense in that case. Using a reference has the problem that you might end up referring to an object which does not exist anymore, so you have to make sure that the YourClass object exists for the duration of the existence of the MyClass object.

c) In the case of a pointer, the problem above still exists, but you can more easily reassign the pointer to a new object.

Inheritance: One can inherit from the YourClass object, so that the members are inherited, such as:

class MyClass : public YourClass
{
public:
  // Some MyClass members...
private:
  // Some other MyClass members...
};

a) This is also very simple to set up for a few classes, but may become unwieldy for general use. For example, if YourClass was a random number generator, it wouldn't necessarily make sense to say MyClass is-a random number generator. One can of course define a wrapper class for the random number generator, say call it Randomizable and then MyClass could inherit from Randomizable, which makes good sense.

I would personally like to know more about the pros and cons of static members, global objects, singletons, and how they are correctly used. So, from a 'meta' point of view, what other methods or patterns would work?

PS. Though I'm asking from a C++ perspective, I guess the same could be said to apply for many other object oriented languages, so don't worry about giving examples in other languages.

A: 

There are basics about C++ class membership access.

  1. You can access a member of your own direct class (public, protected or private)

    class Foo {
    public:
         int fooMember;
    };
    
    
    int main() {
         Foo foo;
         foo.fooMember = 1;
    }
    
  2. You can access protect and public members of your parent class within the child class, and then depending on the inheritance indicator in the child class declaration the members of the parent are passed on to public, next-child, or kept private

    class Animal { 
    
    
    protected:
         int feet;
         int age;
    public:
        enum color { blue, red, green, pink } color;
    
    
     Animal(int feet) { this->feet = feet; }
     bool getFeet() { return feet; }
     void setAge(int a) { age = a; }
    
    
    };
    
    
    class Elephant: public Animal {
    
    
    public:
    
    
     Elephant(void):Animal(4) { }
     int hasFeet(void) { return (feet > 0); }
    
    
    };
    
    
    // Here you can override stuff too so:
    
    
    class Fish: protected Animal {
    public: 
            int teeth;
            enum Type { freshWater, saltWater } type;
        Fish(void):Animal(0) { }
    };
    
    
    class Mackerel: private Fish {
    
    
    public:
            Mackerel(): Fish() { teeth = 12; } /* compiles */
    };
    
    
    class SubMackerel: public Mackerel { 
    public:         
      SubMackerel() { teeth = 8; } /* does not compile teeth not accessible here */
    } ;
    
    
    int main() {
         Elephant pink;
            Fish fishy;
            Mackerel mack;
            pink.color = Animal::blue;
            // this won't compile since color is protected in Fish
            // fishy.color = green;
            fishy.type = freshWater;
            // mack.type = saltWater; // will fail
    }
    
    1. the last way is to declare friends. A friend class can access all public and private members of the class it is a friend to.

Well this should be a start... You can read more about it

Elf King
A: 

Why would you want to directly access another class's member? Does that break encapsulation? I am guessing that accessing the members directly is something you want to do to achieve something else. What is it that you are trying to achieve?

Chetan
I was referring to member functions, and this was more of a discussive type of question than a question to a particular end.
Kristian D'Amato