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.
There are basics about C++ class membership access.
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;
}
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
}
Well this should be a start... You can read more about it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With