I have a project where I am accessing several classes using a pointer to a parent class. I need to know which child class the pointer is referring to, so I am adding a distinct integer ID number to each of them as a constant class variable.
I need to access this variable using the pointer, so I wrote a getter function for that variable. Since the code for the getter function would be the same for all of the child classes, I tried defining the function in the parent class. This roughly lead to the code found below:
class Parent {
public:
virtual void func();
// Getter function
uint8_t getID() {
return classID;
}
// Set ID to a default value
const uint8_t classID = 0;
};
// One of many child classes
class A: public Parent {
public:
void func() {//do something}
const uint8_t classID = 1;
};
int main(){
Parent* childPointer = new A;
uint8_t currentID = childPointer -> getID();
}
However, running this led to currentID being equal to Parent.classID rather than A.classID.
Making the getID function virtual and definining it in each of the child classes made it work as intended, but this would lead to quite a bit of repeated code. I was wondering if there was a way to define the getter function once in the Parent class, and to make it return the correct value? Otherwise, is there a cleaner way to do it?
In C++ each class has it's own namespace. In your code you have a classID in the Parent namespace and a classID in the A namespace. So every instance of A actually has 2 classIDs. The getID() function only sees the classID in the Parent namespace though. This is why it only returns 0.
A better way would be to define constructors which will initialize the classID in Parent:
#include <cstdint>
class Parent {
public:
Parent(): classID(0){}; //Default Parent initializes with 0
Parent(uint8_t ID): classID(ID){}; //Constructor to be called by children
virtual void func(){};
// Getter function
uint8_t getID() {
return classID;
};
const uint8_t classID;
};
// One of many child classes
class A: public Parent {
public:
A(): Parent(1){}; //Every A calls Parent(uint8_t) constructor
void func() {};//do something
//const uint8_t classID = 1; //This is not needed anymore
};
int main(){
Parent* childPointer = new A;
uint8_t currentID = childPointer -> getID();
}
Related
I've been having trouble accessing the "getDegreeProgram()" method in my objects that are set to my array of pointers; all of my baseclass methods are working, but for some reason, my subclass methods aren't even visible. I'm suspecting that I don't have the syntax right, and its converting all of my subclass objects to the baseclass of student.
roster.h:
class roster {
private:
student** classRosterArray; //array of pointers
roster.cpp function that creates my objects and sets them to the array of pointers
void roster::createStudentObject() {
classRosterArray = new student *[5]; //array of pointers
if (degreeProgramInput == "NETWORK") {
classRosterArray[rosterCounter] = new networkStudent();
}
else if (degreeProgramInput == "SECURITY") {
classRosterArray[rosterCounter] = new securityStudent();
}
else classRosterArray[rosterCounter] = new softwareStudent();
}
student.h subclasses in question (they're subclasses of my baseclass "student")
class networkStudent:public student {
private:
int networkDegree;
public:
int getDegreeProgram();
networkStudent();
};
class securityStudent:public student {
private:
int securityDegree;
public:
int getDegreeProgram();
securityStudent();
};
class softwareStudent:public student {
private:
int softwareDegree;
public:
int getDegreeProgram();
softwareStudent();
};
As far as I understood, you are trying to access the elements of classRosterArray and trying to call getDegreeProgram().
For this problem, Make the getDegreeProgram() virtual function.
student.h
class student {
...
public:
virtual int getDegreeProgram() = 0; // pure virtual function
};
Subclasses of student
class networkStudent:public student {
private:
int networkDegree;
public:
virtual int getDegreeProgram();
networkStudent();
};
class securityStudent:public student {
private:
int securityDegree;
public:
virtual int getDegreeProgram();
securityStudent();
};
class softwareStudent:public student {
private:
int softwareDegree;
public:
virtual int getDegreeProgram();
softwareStudent();
};
Suggestion:
In this case, Because getDegreeProgram() seems to be a getter function, I think you should declare it as a const function.
Edit:
As rightly said by Richard, In C++ 11, override keyword was introduced for this purpose for the sub classes. So, instead of writing virtual int getDegreeProgram();, you could write int getDegreeProgram() override; also.
There are two you ways you can go about it.
Runtime Polymorphism - This method will require less code refactoring but at the cost of runtime. Each instance of a polymorphic class will have a pointer(vptr) to a table(vtable) of pointers to the different versions of the virtual function. This table will be used for finding the right version of the virtual function at runtime.
You can achieve runtime polymorphism here by making the getDegreeProgram function virtual in base class ie., Student and override it in derived classes ie., securityStudent, networkStudent and softwareStudent.
class Student {
...
public:
virtual int getDegreeProgram() = 0; // notice the virtual keyword and 0 at the end.
// 0 is for saying that it is pure virtual, meaning
// we don't have any definition for this function in
// this class. Such a class is also called as
// abstract class
...
}
class securityStudent : Student {
...
public:
int getDegreeProgram() override
{
// do the stuff you want to do
}
...
}
// driver stub
...
Student *student;
securityStudent sStudent;
networkStudent nStudent;
.
.
student = &sStudent;
student->getDegreeProgram(); // calls security student implementation of getDegreeProgram
student = &nStudent;
student->getDegreeProgram(); // calls network student implementation of getDegreeProgram
...
Static Polymorphism or CRTP or Simulated Dynamic Binding - This method does the same thing as above but with the advantage of knowing the type at compile time by means of some casting magic (below). Even this approach has its limitation like kludgy syntax and some amount of refactoring which is a lot more than in the 1st case and lack of readability due to terseness of templates etc.
The trick here is to get the derived class' information at compile time and typecast the this pointer of the base class to that of the derived class. :-)
template <typename StudentType>
class Student {
...
public:
int getDegreeProgram()
{
return (static_cast<StudentType*>(this))->getDegreeProgramImpl();
}
...
}
class securityStudent : public Student<securityStudent> {
...
public:
int getDegreeProgramImpl()
{
// write your specifc implementation here
}
...
}
// driver stub
...
securityStudent sStudent;
networkStudent nStudent;
.
.
sStudent.getDegreeProgram(); // calls security student implementation of getDegreeProgram
nStudent.getDegreeProgram(); // calls network student implementation of getDegreeProgram
...
Let me first say this is a purely academic question, since what I want to do can be better accomplished with multiple layers of inheritance.
That said, I wonder if it's possible to override a virtual function with an existing function without writing a wrapper or adding any inheritance layers. Code:
int myfunc2() { return 2; }
class Parent {
public:
virtual int myfunc() { return 0; }
};
class Child1 : public Parent {
public:
int myfunc() override { return 1; }
};
class Child2 : public Parent {
public:
// There a way to do this?
// int myfunc() = myfunc2;
// instead of this?
int myfunc() { return myfunc2(); };
};
int main() {
Child2 baz;
return baz.myfunc();
}
I'd like to override myfunc in the definition of Child2 by simply "forwarding" the declaration to the existing declaration of myfunc2.
Is this, or something akin to it, possible?
Context: I've got a bunch of child classes, some of which have identical definitions of myfunc, some of which do not. A better solution is to create an intermediate child class that defines the common myfunc and have the pertinent children inherit from that instead.
// There a way to do this?
// int myfunc() = myfunc2;
// instead of this?
int myfunc() { return myfunc2(); };
No, there isn't.
There is a problem.
A non-static member function accepts one more implicit parameter: pointer to the object itself. While a stand-alone function does not have such a parameter, For example you may not use the keyword this or member access syntax inside the definition of a stand alone function.
I'd like to be able to group similar functions in a class into a group so I don't need to append each name with what it's about.
I've seen this question which says that you can't have namespaces within classes. I've also seen this question which proposes using strongly typed enums. The problem here though, is that I'm not sure whether or not these enums can actually accomodate functions?
The problem contextualised:
class Semaphore
{
public:
void Set(bool State){Semaphore = State;}
bool Get(){return Semaphore;}
void Wait()
{
while (Semaphore)
{
//Wait until the node becomes available.
}
return;
}
private:
bool Semaphore = 0; //Don't operate on the same target simultaneously.
};
class Node : Semaphore
{
public:
unsigned long IP = 0; //IP should be stored in network order.
bool IsNeighbour = 0; //Single hop.
std::vector<int> OpenPorts;
//Rest of code...
};
Currently, NodeClass.Get() is how I can get the semaphore. However this introduces confusion as to what Get() actually gets. I'd like to have something akin to NodeClass.Semaphore::Get(). Otherwise I'd have to have the functions as SemaphoreSet(), SemaphoreGet(), and SemaphoreWait(), which isn't too well organised or nice looking.
I had thought of just having the Semaphore class on it's own, and instantiating it within the other classes, but if I could stick with the inheritance approach, that would be nicer.
So essentially, is it possible to access inherited methods like InheritedClass.Group::Function()?
If you really want to do this, you could force the user to call with the base class name by deleteing the member function in the subclass:
class Base {
public:
void Set(bool) { }
};
class Derived : public Base {
public:
void Set(bool) = delete;
};
int main() {
Derived d;
// d.Set(true); // compiler error
d.Base::Set(true);
}
However, if the semantics of calling Set on the subclass are significantly different than what you'd expect them to be when calling Set on the base class, you should probably use a data member and name a member function accordingly as you've described:
class Base {
public:
void Set(bool) { }
};
class Derived {
public:
void SetBase(bool b) {
b_.Set(b);
}
private:
Base b_;
};
int main() {
Derived d;
d.SetBase(true);
}
I want to design a parent class
//Parent.h
class Parent {
private:
int currentId;
static int getIdSquare(); //Just random function for simplicity
}
//Parent.cpp
#include "Parent.h"
int Parent::getIdSquare() { return this->currentId * this->currentId };
Of course this won't work! because you cannot access non-static variable in static function but hold on.
I want my child class to be like this
//Child.h
#include "Parent.h"
class Child : public Parent {
private:
static int index;
};
//Child.cpp
#include "Child.h"
int Child::index = 5;
So that in main when I call Child::getIdSquare(); I will get 25. And I should not be able to call Parent::getIdSquare() because its private. How do I go on about creating something like. This is a non-working code just to illustrate the concept. So if I make another child class i can specified the index in its own body. I want to call the method statically.
Please help me figure out this puzzle!
It sounds like what you are after is really a virtual static function. Unfortunately, that doesn't exist in C++.
Also, Child::getIdSquare() will also be private, and inaccessible in main().
If you need to statically pass a value from a child class to its parent, you may need to do it during the inheritance itself via a template argument.
template <int id>
class Parent
{
public:
static int getIdSquare() { return id * id; }
}
class Child : public Parent<5>
{
}
Then Child::getIdSquare() will return 25, as required. It doesn't get around the fact that you want Parent::getIdSquare to be private, while making it public in Child though. For that you would need to declare it as private in Parent and then declare it again as public in Child, with an implementation of return Parent<5>::getIdSquare();
Still not ideal, but it's a relatively vague question, so hard to really find a perfect solution here...
I am not sure I completely understand the question, but I see two alternatives. If you want to implement type-specific properties you could go with traits:
template<typename T>
struct Square {};
class Parent {
};
class Child: public Parent {};
template<> Square<Parent> {
};
template<> Square<Child> {
static constexpr int getIdSquare() {
return 25;
}
};
void foo() {
// this will not compile
//auto id = Square<Parent>::getIdSquare();
// but this will
auto id = Square<Child>::getIdSquare();
}
An alternative design would be to use the template method pattern, but this uses dynamic dispatch. It would look like this:
class Parent {
public:
int getSquareId() {
return currentId() * currentId();
}
private:
virtual int currentId() = 0;
};
class Child: public Parent {
private:
virtual int currentId() override {
return 5;
}
};
Suppose we have the following:
class Parent {
public:
virtual void run() {
for (int i = 0 ; i < bar.size() ; ++it)
cout << i << "\n" ;
};
protected:
static vector<int> foo() {return vector r({1,2,3,4,5});};
static vector<int> bar;
}
vector<int> Parent::bar = Parent::foo();
Now if I create a child class whose run function would be called externally, how can I redefine the foo function to return something else while still using the parent run function?
Edit: Sorry let me add some more information. Suppose the virtual function run() is a lot of code, all of which is essentially the same. The only difference in the parent and child classes is what values I want specified in the vector bar, so it would seem to be a little wasteful to redefine the virtual function in the child class. However, if you redefine Child::bar, and call Child::run(), the Parent::bar is used since it's defined in the parent class. Is there some way to have the line "vector Parent::bar = Parent::foo();" know in the Child class to use "Child::foo();"?
As usual. Override base virtual function in derived class.
class Parent {
public:
virtual bool run() {return bar;};
static bool foo() {return true;};
static bool bar;
};
class Child: public Parent
{
public:
static bool foo() { return false;};
};
You can then still use base version applying Base:: scope resolution:
int main() {
bool bc = Child::foo();
bool bp = Parent::foo();
std::cout << bc << bp;
return 0;
}
http://ideone.com/TdaNQ5
I am not sure what do you exactly want here. However, you can override the static function like this,
class Child: public Parent
{
public:
static bool foo() {return false;};
};
You really don't say much about your problem, therefore it is hard to distinguish what you need from what is potentially an XY problem.
One potential problem with your architecture is that you have a Parent and a Child classes that share a static variable bar yet you seem to initialize them differently for Parent and Child classes. However, there is only one bar that is shared both by Parent and Child objects, independently of who wrote to it last.
So, what do you expect when both a Parent and a Child objects are used simultaneously? The answer you look for depends on your answer on that one. In particular, if your answer is 'it is not designed to have Parent and Child objects operate simultaneously', then both classes should definitely not share a static variable.