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?
Related
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!)
Suppose I have a class coming from the software package, so I do not have a way to change the design, that has the following form:
class A
{
public:
A(int degree)
{
...
initialize_points();
...
}
...
private:
...
void initialize_points()
{
int number = 1;
// proceed to do computations using the number specified above
...
}
...
}
What I need is to have a class B being similar to class A in everything but the number specified in the function initialize_points(). Say, I want it to be 34 instead of 1.
Due to lack of experience I don't quite understand how I can derive such a class B (and should I do so, maybe it is better to write this as a new class mimicking the implementation of A?) from the class A since the function, whose behavior I want to override is the private member of the base class.
Thank you
The short answer is that this cannot be done in C++. The primary mechanism by which a derived class could override what its base class does is virtual functions. Unless the base class defines virtual functions, there's nothing that can be done in the derived class to override it.
I have the following class hierarchy for graphs:
typedef vector<int> ArrayI;
typedef vector<Array<long>> Mat2DB;
typedef vector<ArrayI> adjList;
class baseGraph {
int nodes;
ArrayI degree;
//some member functions.
}
class matGraph: public baseGraph {
Mat2DB matrix;
//member functions.
}
class lMatGraph: public matGraph {
ArrayI labels;
//member functions.
}
class listGraph: public baseGraph {
adjList list;
//member functions.
}
class lListGraph: public listGraph {
ArrayI labels;
//member functions.
}
Now in this class I have many other functions, mostly virtual, so that when I get to call the proper function while using the base class pointer.
For example I have a function sssp(int node) which implements single source shortest path. The implementation are both different for class matGraph and class listGraph which are adjacency matrix representation and adjacency list representation of graphs respectively. Now there is not need to change the definition for labelled version of these graphs so I do not define these functions again in lListGraph and lMatGraph
Now the only problem I am havin is with setLabel(const ArratI &) in lListGraph and lMatGraph classes. I need this function to be virtual so that it gets called through base class pointer, but at the same time I do not have anything such as labels for classes matGraph and listGraph.
I do not know if my design hierarchy is correct or not, but it seemed intuitive to me. So any comments on that would be good. What can I do with the setLabel function. Is it okay to have such a function(to me it looks like kind of a workaround so this question) or do I need to reconsider my class hierarchy.
P.S.: I would also love if there are some books from which I can practice design questions like these. I run into these delimma offten and am not sure what to do of them.
EDIT:
Use of class graph is used in another class clustering where I have a member baseGraph *graph i.e.
class clustering {
baseGraph *graph;
}
I am storing the pointer to base class here so that I can use the different algorithms(implemented as functions) from class graph. For clustering class it again depends what type of graph I want to use.
Maybe this ?
typedef vector<int> ArrayI;
typedef vector<Array<long>> Mat2DB;
typedef vector<ArrayI> adjList;
class baseGraph {
int nodes;
ArrayI degree;
virtual void sssp(int node);
//some member functions.
}
class labeledGraph: public virtual baseGraph {
ArrayI labels;
virtual void setLabel(const ArratI &);
//member functions.
}
class matGraph: public virtual baseGraph {
Mat2DB matrix;
//member functions.
}
class lMatGraph: public virtual matGraph, public virtual labeledGraph {
//member functions.
}
class listGraph: public virtual baseGraph {
adjList list;
//member functions.
}
class lListGraph: public virtual listGraph, public virtual labeledGraph {
//member functions.
}
I'm assuming here that you incorrectly inherited from graph when you should have been inheriting from baseGraph (typeo) - though even if not it comes down to same point.
Also rough coding, if you have questions or if there are mistakes feel free to ask.
You say that setLabel should be called through base class pointer, so this necessarily means that it should be declared in the base class, even though it doesn't make sense. You can implement setLabel for graphs that are not labelled in two possible ways:
Do nothing - just ignore the request for setting the labels
Throw an exception (e.g. abort) - something is probably wrong, so the user should know that!
Each way is a workaround, so you should consider why setLabel should be called through base class pointer, and possibly change this decision. I'd expect, if you really need a labelled graph for your algorithm, use the appropriate type instead of a base-class type - then you don't need to do any hacks to the base class.
Note that if you keep adding stuff to the base class that corresponds to each derived class, you are going to end up with a lot of mess in the base class - no good!
In addition, the following may solve your problem with setLabel and make your class hierarchy "healthier".
Consider moving your basic algorithms like sssp away from the class declarations - make them overloaded free-standing functions instead of member functions. This way you won't need to declare sssp in the base class either. If you adopt this guideline, when you implement a new algorithm, the compiler will check all function calls, and issue an error if one is missing (this is better than a crash or getting incorrect results).
class baseGraph {
int nodes;
ArrayI degree;
// a minimum number of member functions (e.g. getNode; getEdges)
}
class matGraph: public graph {
Mat2DB matrix;
}
class lMatGraph: public matGraph {
ArrayI labels;
void setLabel(const ArrayI &);
}
int sssp(const matGraph& graph, int node)
{
// Some code
}
int sssp(const lMatGraph& graph, int node)
{
// Some code; here you can use labels
}
This is discussed in the Effective C++ book (Effective C++ Item 23 Prefer non-member non-friend functions to member functions)
It all boils down to a simple choice. What should happen if I try to set a label in a graph that does not in fact support labels?
Nothing (the attempt may be logged but is otherwise ignored)
A catastrophic failure
I should not be able to even try (the compiler should not let me)
That's it. These are all your options.
The first two options are easy, you just write a virtual function that reports an error (logs it, or throws an exception).
The third one is interesting. It means there is no corresponding virtual function at all. Not in your class and not in any base class. This goes against your design but your design is not necessarily perfect.
So how do you set a label then? Through something that is not a pointer to your base class :) It can be a pointer to another base class (a mixin ― you use multiple inheritance to add labeling functionality to graphs). Or you may templatize your design so that the hierarchy does not really matter and you always statically know the most derived type of your objects.
Following is an interface:
class SIM{
private:
//private data
public:
Send();
Display();
Recieve();
Encrypt();
};
How do I restrict access to Display() function (it has to be lie in public part) of SIM to other classes except one class (Neo etc). I don't want to use friend etc.
Edit:
I can move the display() to private , how do i allow only NEO class to access it? 0_o
You can have Display take a dummy const reference to a type that can only be created from a privately nested within the class you want to be able to make the calls. Then in order to pass that type to Display you have to be a member of that class.
But why would you do that when friend does exactly what you want?
Code example:
class AllowedCaller
{
private:
class FriendHackHelp
{
};
public:
class FriendHack
{
public:
// You can only create a FriendHack from inside this class now...
FriendHack(const FriendHackHelp&) { }
};
void run();
};
class Displayer
{
public:
void Display(const AllowedCaller::FriendHack&) { /* Whatever */ }
};
void AllowedCaller::run()
{
Displayer d;
d.Display(FriendHack(FriendHackHelp()));
}
int main()
{
return 0;
}
In C++ this is simply not possible. What you could do is to pass the Neo class as a parameter to the Display() function as a reference and you would have a similar effect.
You can also split your SIM class to 2 classes: Displayable (with Display method) and SIM (with the remaining methods). Then, when creating Neo class, simply do not extend the Displayable class.
Let me ask you a question: What exactly is neo? Is it able to be inherited from SIM? If so, make Display() protected as opposed to private.
I've been wondering about this too in the past, check these questions:
programming language with granular method and property access
a way in c++ to hide a specific function
However,i come up to terms of the idea that the only way to implement this (in c++ at least) is to create multiple interfaces for each client class, and make each interface a friend of the client class that will access it
so you need to implement all and each of the interfaces with multiple inheritance
I have a class that only really ever needed by classes in a certain class hierarchy. I wanted to know if it is possible to nest the class in the highest class's protected section and have all the other classes automatically inherit it?
"Inherit" is the wrong word to use since it has a very specific definition in C++ which you don't mean, but yes you can do that. This is legal:
class A {
protected:
class Nested { };
};
class B : public A {
private:
Nested n;
};
And code that is not in A or something that derives from A cannot access or instantiate A::Nested.