Is it possible for classes to work together in C++? - c++

I have this large class that I want to separate into different classes. The reason why it was large because the class had many private variables and functions that are needed to run the program. I was tired of scrolling down the 1000+ lines of code trying to add or edit code. I am wondering if it is possible for the classes to interact with one base class that includes all the private/protected variables it needed to operate, or simply have them as global variables.
I am aware of inheritance as I tried having the separate classes be derived from the base class, by doing something similar to this:
#include <iostream>
class Base {
public:
void sayPrivateVar() {
std::cout << privateVar;
}
protected:
std::string privateVar = "I am a protected variable!";
};
class Derived : public Base {
public:
void manip() {
base->privateVar = "That was updated from a derived class";
}
private:
Base* base;
};
int main() {
Base base;
Derived derived;
derived.manip();
base.sayPrivateVar();
return 0;
}
EDIT: Without creating another object inside a class.

it depends on your class and what you have in it. It is often better not have inheritance because derived classes may then get member variables that they don't need. There are a few other ways you can do. One way would be to group you private variables in different classes and then have member variables in the first class.
E.g.
class X {
int x;
int y;
int angle;
...
};
becomes
class XYVector;
class X {
XYVector v;
};
class XYVector
{
int x;
int y;
int angle;
};
You can continue in this direction and instead of making them concrete class like XYVector above have them as interfaces : to have it more elaborate and flexible check out https://en.wikipedia.org/wiki/Composition_over_inheritance
At any rate: avoid having globally declared variables.

This is a good question and the answer is absolutely. Inheritance is actually a very good solution in this particular context since that is how object code shares it's scope with other classes. One important thing to note here is that how you call your derived class is important because the inherited scope is set along with the derived class (i.e. declaring it public base would inherit the public and protected methods as opposed to declaring it private which would give the derived class even more access!)

Related

C++ Inheriting functions that use class variables

Let's say i have an abstract class thats main purpose is to store a vector of numbers, called NumberVector. Then, I have two classes that inherit NumberVector that are called SortableNumberVector and SearchableNumberVector. Now, I want to make an adapter class that combines these two, and I make a class called SortableSearchableNumberVector, which inherits both of these. I want the final class to call functions from the inherited classes, but still retain data of it's own. Here's how I have laid it out:
class SortableSearchableNumberVector : public SearchableNumberVector, public SortableNumberVector
{
protected:
vector<int> numbers;
int selectedNumber;
public:
void selectNumber(int index)
{ SearchableNumberVector::setSelected(index); }
void sortNumbers()
{ SearchableNumberVector::sort(); }
}
When I run this, the two class variables are unchanged. What is causing this to happen?

what is the difference between polymorphism and inheritance

I am confused about the concepts of inheritance and polymorphism. I mean, what is the difference between code re-usability and function overriding? Is it impossible to reuse parent class function using inheritance concept or else is it impossible to override parent class variables using Polymorphism. There seems little difference for me.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
My doubt is about the difference between the code reuse and function overriding.
Lets start with your example.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
Inheritance: Here you are deriving class B from class A, this means that you can access all of its public variables and method.
a = a + 1
Here you are using variable a of class A, you are reusing the variable a in class B thereby achieving code reusability.
Polymorphism deals with how a program invokes a method depending on the things it has to perform: in your example you are overriding the method get() of class A with method get() of class B. So when you create an instance of Class B and call method get you'll get 'hi' in the console not 'welcome'
Function inheritance allows for abstraction of behaviour from a "more concrete" derived class(es) to a "more abstract" base class. (This is analogous to factoring in basic math and algebra.) In this context, more abstract simply means that less details are specified. It is expected that derived classes will extend (or add to) what is specified in the base class. For example:
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
private:
int m_commonProperty;
};
class Subtype1 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
char getProperty(void) const { return m_specificProperty1; }
private:
char m_specificProperty1;
};
class Subtype2 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
float getProperty(void) const { return m_specificProperty2; }
private:
float m_specificProperty2;
};
Note that in the above example, getCommonProperty() and setCommonProperty(int) are inherited from the CommonBase class, and can be used in instances of objects of type Subtype1 and Subtype2. So we have inheritance here, but we don't really have polymorphism yet (as will be explained below).
You may or may not want to instantiate objects of the base class, but you can still use it to collect/specify behaviour (methods) and properties (fields) that all derived classes will inherit. So with respect to code reuse, if you have more than one type of derived class that shares some common behaviour, you can specify that behaviour only once in the base class and then "reuse" that in all derived classes without having to copy it. For example, in the above code, the specifications of getCommmonProperty() and setCommonProperty(int) can be said to be reused by each Subtype# class because the methods do not need to be rewritten for each.
Polymorphism is related, but it implies more. It basically means that you can treat objects that happen to be from different classes the same way because they all happen to be derived from (extend) a common base class. For this to be really useful, the language should support virtual inheritance. That means that the function signatures can be the same across multiple derived classes (i.e., the signature is part of the common, abstract base class), but will do different things depending on specific type of object.
So modifying the above example to add to CommonBase (but keeping Subtype1 and Subtype2 the same as before):
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
virtual void doSomething(void) = 0;
virtual ~CommonBase() { }
private:
int m_commonProperty;
};
Note that doSomething() is declared here as a pure virtual function in CommonBase (which means that you can never instantiate a CommonBase object directly -- it didn't have to be this way, I just did that to keep things simple). But now, if you have a pointer to a CommonBase object, which can be either a Subtype1 or a Subtype2, you can call doSomething() on it. This will do something different depending on the type of the object. This is polymorphism.
void foo(void)
{
CommonBase * pCB = new Subtype1;
pCB->doSomething();
pCB = new Subtype2;
pCB->doSomething(); // Does something different...
}
In terms of the code sample you provided in the question, the reason get() is called "overriding" is because the behaviour specified in the B::get() version of the method takes precedence over ("overrides") the behaviour specified in the A::get() version of the method if you call get() on an instance of a B object (even if you do it via an A*, because the method was declared virtual in class A).
Finally, your other comment/question about "code reuse" there doesn't quite work as you specified it (since it's not in a method), but I hope it will be clear if you refer to what I wrote above. When you are inheriting behaviour from a common base class and you only have to write the code for that behaviour once (in the base class) and then all derived classes can use it, then that can be considered a type of "code reuse".
You can have parametric polymorphism without inheritance. In C++, this is implemented using templates. Wiki article:
http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Parametric_polymorphism

Organizing functions within a class

I want to put all of a classes functions into a "subdomain" (what is the right term for this?), such as the functions part of myClass.functions.function1();
So how should one rewrite this for that purpose?
class MYCLASS {
private:
int data;
public:
int function1();
int function2();
int function3();
};
So that the class could then be used:
MYCLASS myClass;
myClass.functions.function1();
rather than using just myClass.function1();.
You can make these free functions in some descriptive namespace, or you can emplace them inside a nested class. However, both of these imply access to members only through the original class's interface, meaning you will still need some public functions inside the class itself.
Otherwise, it's already clear that these are functions, so I would simply not do this. If you want to because you have loads and loads of functions, then you have too many functions, and your class almost certainly does too many things.
Depending our your design (which needs to be object-oriented but not necessarily) you can define a new namespace or an struct or a class which is called nested classes!
for example:
class A {
public:
int a;
class B {
public:
void do_something();
} bObject;
};

Abstract base member variable in base class

I want to specify an interface which requires an abstract class to have a certain type as a member variable.
I'll try to replicate the situation here:
class Blob {
int data[32];
};
class Worker {
string name;
abstract void workOn(Blob&) = 0;
}
class Abstract {
vector<shared_ptr<W>> workerList;
Blob allTheStuff;
abstract void somethingElse() = 0;
void doAllTheWork() {
for (w : workerList) {
w->workOn(allTheStuff);
}
}
};
class B_Blob : public Blob {
int moreData[4096];
};
class BulbasaurTrainingCamp : public Abstract {
B_Blob allTheStuff;
void somethingElse() {} // implemented
// this class will accept Bulbasaurs into workerList
};
class Bulbasaur : Worker {
Bulbasaur(): name("Fushigidane") {}
void workOn(Blob& b) {
// bulbasaurs cover *all* their workspace with crap
for (int i=0; i<sizeof(b.data[0])/sizeof(b.data); ++i) {
b.data[i] = *((int*)&("crap"));
}
for (i=0; i<sizeof(b.moreData[0])/sizeof(b.moreData); ++i) {
b.moreData[i] = *((int*)&("crap"));
}
}
Here, the abstract bas class has a Blob, but the instance of BulbasaurTrainingCamp has a derived B_Blob. It appears that since I gave it the same name, the compiler accepts it.
Is there a name for this? What I want to know is what the behavior is when I do this. Have I overridden the Blob with the B_Blob?
I am basically not sure about whether there is an inaccessible base Blob instance hanging around inside of BulbasaurTrainingCamp. My expectation is that each Bulbasaur will write 16512 (not 16384) bytes of crap across the two member variables of B_Blob. I am hoping that C++ will actually do what appears to be the sensible thing. It's a case of, "it compiles so I think I should be happy, but I'm still not totally sure it's doing what I think it should be doing".
#include<iostream>
#include<vector>
using namespace std;
int main()
{
class base
{
public:
int sameName;
base(int x):sameName(x){}
};
class derived : public base
{
public:
int diffName;
int sameName;
derived(int x,int i,int j):base(x),diffName(i),sameName(j){}
};
derived example(1,2,3);
cout<<example.sameName<<endl;
cout<<example.diffName<<endl;
cout<<example.base::sameName<<endl;
}
The result is 3 2 1.
I hope the example could be helpful.
A base class, even an abstract one, will be included in its entirety within any derived classes. The new allTheStuff name hides the old one, but does not suppress its inclusion; the base class version can still be accessed using Abstract::allTheStuff. Worse, the function doAllTheWork will end up accessing the base class allTheStuff because it can't possibly know there's an identically-named member variable in a subclass.
If you want this kind of behaviour, you have a few decent options:
Don't put any meaningful code or data in the base class; leave it as a pure interface. This may result in code duplication (but you may be able to factor it out into new base classes or shared helper functions).
Use a dynamically sizable container type as the Blob, so you can dynamically ask for more or less space in the constructor.
Make Blob a separate inheritance hierarchy (e.g. B_Blob and S_Blob inherit from an abstract Blob with differing amounts of space allocated), with a virtual function in Abstract that returns the Blob to use.
You seem to be somehow assuming that this code compiles using C++. It certainly doesn't. Even after patching about various of the C++/CLI specifics, it remains that a Blob does not have a data member called moreData and the only way to get at it (using C++) is to use a suitable cast.
The BulbasaurTrainingCamp objects will have two members called allTheStuff, one of type Blob and one of type B_Blob. Which one you get depends on which type you are looking at (since all members are private, you won't get any, but let's ignore that detail) and/or which qualification you use:
BulbasaurTrainignCamp btc;
B_Blob& b_blob = bts.allTheStuff;
Blob& blob1 = bts.Abstract::allTheStuff;
Abstract& abstract;
Blob& blob2 = abstract.allTheStuff;
That is, when using something which looks like a BulbasaurTrainingCamp you can access both the Blob and the B_Blob objects but you need to use qualification to access Abstracts allTheStuff member. When using an Abstract you can only access Abstracts Blob object.

In what ways can a class access members of another class?

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
}
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
I have been looking for the answer about the kind of same thing , and landed here.
Buy anyway , atleast I should tell you what till now I have learned about this problem.
Avoid using another class as data member , if that's not the case and you have to use it, then use pointer to that another class.
Now, if you are using pointer to the another class , always deep copy , so you have to provide a copy constructor with a deep copy to avoid invalid address assignment .
Or just use smart pointers .