How do I access member variables inside an overridden base class function?
//Overridden base class function
void handleNotification(s3eKey key){
//Member variable of this class
keyPressed = true; //Compiler thinks this is undeclared.
}
Complier is complaining that keyPressed is not declared. The only way I can figure out how to access it is declare keyPressed as a public static variable and then use something like:
ThisClass::keyPressed = true;
What am I doing wrong?
//Added details-----------------------------------------------------------
ThisClass.h:
include "BaseClass.h"
class ThisClass: public BaseClass {
private:
bool keyPressed;
};
ThisClass.cpp:
include "ThisClass.h"
//Overridden BaseClass function
void handleNotification(s3eKey key){
//Member variable of ThisClass
keyPressed = true; //Compiler thinks this is undeclared.
}
BaseClass.h:
class BaseClass{
public:
virtual void handleNotification(s3eKey key);
};
BaseClass.cpp
include 'BaseClass.h"
void BaseClass::handleNotification(s3eKey key) {
}
Is this method defined outside of the class definition? In other words, is your code structured like so:
class ThisClass {
...
};
// method defined outside of the scope of ThisClass declaration, potentially
// in a completely different file
void handleNotification(s3eKey key) {
....
}
If so, you need to declare the method like this:
void ThisClass::handleNotification(s3eKey key){
keyPresssed = true;
}
Otherwise the compiler will not know that the handleNotification() method being implemented is the one which belongs to ThisClass. Rather, it will assume that it is not part of the ThisClass implementation, so it won't have automatic access to ThisClass's variables.
The correct way to override a function is as follows.
class base {
protected:
int some_data;
virtual void some_func(int);
public:
void func(int x) { some_func(x); }
};
void base::some_func(int x)
{ /* definition, may be in some source file. */ }
class derived : public base
{
protected:
virtual void some_func(int); // this is not base::some_func() !
};
void derived::some_func(int x)
{
some_data = x; // example implementation, may be in some source file
}
edit Note that base::some_func() and derived::some_func() are two different functions, with the latter overriding the former.
Related
My goal is to construct a derived classes nested class from the interface. However the nested classes don't have the same constructors. The question is how can I make an interface to create two different "sub-nested" classes.
Constraints:
Cannot use Heap
Nested Classes' Methods cannot be called before it is constructed
C++ 17
ITest::INestedTest* MakeTest(ITest* test, ITest::Config config)
{
// Can't call directly because it's not on the interface i.e. test.InitializeNestedTest ...
// Only workable situation is this:
if (condition)
{
auto myTest = static_cast<Test2::Test*>(test);
int p = 2;
return myTest->InitalizeNestedTest(config, p);
// ERROR function returning abstract class not allowed
} else {
auto myTest = static_cast<Test1::Test*>(test);
return myTest->InitalizeNestedTest(config);
// ERROR function returning abstract class not allowed
}
}
This static cast didn't return what I wanted previously because I was returning a pointer to a locally defined variable, which was pointed out in the comments. How am I able to return a class from this since it's an abstract class, do i need to cast it again or make multiple functions?
Test1::Test myTest;
auto myNestedTest = myTest.InitializeNestedTest(config);
I've thought of a few options but none of them seem right, or I'm not entirely sure how to implement them
Have an overloaded Virtual function for each type on the interface and then override them on the subclass (not sure if possible and doesn't seem like the right way to do it)
Extend the Config struct Test2 namespace so that it includes parameter p, so that they all have the same prototype and put it on the interface. (is it possible to "extend" the struct" from the interface?)
Maybe use a different type of cast, or do so in a different way?
I've included the definitions of my Interface and two subclasses for reference.
class ITest
{
//other things in ITest.hpp not relevant to question
public:
struct Config
{
int a;
bool enable;
};
class INestedTest
{
public:
virtual void Enable() const = 0;
virtual void Configure(Config const& config)
{
if(config.enable)
{
Enable();
}
}
};
};
namespace Test1
{
class Test : public ITest
{
public:
class NestedTest : public ITest::INestedTest
{
public:
NestedTest(Config const& config)
{
Configure(config);
}
void Enable() const override
{
//impl
}
}; // End NestedTest
NestedTest InitalizeNestedTest(Config const& config)
{
return NestedTest(config);
}
};
};
namespace Test2
{
class Test : public ITest
{
public:
class NestedTest : public ITest::INestedTest
{
public:
using Parameter = int;
NestedTest(ITest::Config const& config, Parameter p)
{
Configure(config);
}
void Enable() const override
{
//impl
}
}; // End NestedTest
NestedTest InitalizeNestedTest(Config const& config, NestedTest::Parameter p)
{
return NestedTest(config, p);
}
};
};
Maybe you could make the object static so it's declared in RAM at compile time (and not heap or stack).
class MainClass
{
string _ClassName;
public:
string MainClass(string _C)
{
_ClassName = _C;
}
SubClass s1;
};
class SubClass : public MainClass
{
public:
string Method_1()
{
return a;
}
string Method_2()
{
return a;
}
};
Why is SubClass s1 not working can someone tell me please what am i missing I'm new to OOP.
I want to instantiate SubClass object inside MainClass but it doesn't seems to work.
basically, my aim is to access SubClass functions when MainClass object is instantiated in Main method something like this:
int Main()
{
MainClass M1("test");
M1.s1.Method_1(); <--------- this
}
The first problem is, that the MainClass does not know a thing about SubClass when you're trying to instantiate the object.
You need to use a forward declaration and a pointer to make it work.
Header file:
class SubClass; //Forward declaration, allows pointer.
class MainClass
{
string _ClassName;
public:
MainClass(string _C); //No return type on constructor
~MainClass();
SubClass *s1; //Size: 4 Bytes on 32bit system
protected:
MainClass();
};
class SubClass : public MainClass
{
public:
string Method_1();
string Method_2();
};
CPP file:
#include "headerFile.h"
MainClass::MainClass(string _C) :
_ClassName(_C),
s1(new SubClass) //Class definition is now known.
{
}
MainClass::MainClass() : s1(nullptr) //Nullptr -> No new object, no infinite recursion.
{
}
MainClass::~MainClass()
{
delete s1; //Do not forget to clean up your pointer.
}
string SubClass::Method_1()
{
return "a";
}
string SubClass::Method_2()
{
return "a";
}
Call:
int main()
{
MainClass M1("test");
M1.s1->Method_1(); //-> to dereference the pointer.
}
The second problem, as Richard Critten has pointed out, is an infinite recursion, which will cause your program to crash very quickly.
Each time you instantiate a SubClass, you also create a subclass, which creates yet another MainClass etc.
To circumvent this, you'll need a protected constructor, which does NOT create the subclass member.
The third problem:
You are returning a in your methods, which suggests a variable.
If you meant to return 'a', you need to put them into quotation marks.
Finally, in order to get it to compile, you'll need to write Main with a small m (int main()), otherwise the linker will complain.
However, as Mr. 'Not a number' correctly stated, the above edits only make your code compile.
What you likely are actually after however would be using virtual functions, which can be overridden by sub classes to specialize the behavior.
An example code using actual inheritance:
Header file:
class MainClass
{
string _ClassName;
public:
MainClass(string _C); //No return type on constructor
virtual ~MainClass(); //All base classes that have at least one virtual method should also have a virtual destructor, even if it is empty.
virtual void doSomething();
};
class SubClass : public MainClass
{
public:
SubClass(string className);
void doSomething();
};
CPP file:
#include "headerFile.h"
#include <stdio.h>
MainClass::MainClass(string _C) : _ClassName(_C)
{
}
MainClass::~MainClass()
{}
void MainClass::doSomething()
{
printf("Called from MainClass\n");
}
SubClass::SubClass(string className) : MainClass(className)
{
}
void SubClass::doSomething()
{
printf("Called from SubClass\n");
}
Call:
int main()
{
MainClass M1("test");
SubClass sub("SubClass");
MainClass *pointer = ⊂
M1.doSomething(); //Outputs 'Called from MainClass'.
sub.doSomething(); //Outputs 'Called from SubClass'.
pointer->doSomething(); //Also outputs 'Called from SubClass', since it points to sub and because sub overrides the behaviour from MainClass.
}
To call the parent method from the child method, you need to invoke the method from within the override with the parent class.
Example (in SubClass::doSomething): MainClass::doSomething().
I'm trying to write a unittest but I'm running into some problems.
I've got a class which has an int to keep track of the current state. All classes that are inherited of this class can change the state by calling the protectedFunction.
class RandomClass
{
public:
RandomClass()
{
mState = 0;
}
protected:
void protectedFunction()
{
++mState;
}
private:
int mState;
friend void UNITTEST_setMState(int state);
friend int UNITTEST_getMState();
};
Now i'd like to write a unittest for this class. So I created a new class which inherits the previous class. To Properly test all the states I need to set the state, and I need to get the state to assert it. I've tried using a friend function but it does not seem to work.
class UnittestRandomClass : public RandomClass
{
public:
void wrapperProtectedFunction()
{
protectedFunction();
}
void UNITTEST_setMState(int state)
{
this->mState = state; // Apparently not like this
}
int UNITTEST_getMState()
{
return this->mState; // Apparently not like this
}
};
int main() {
UnittestRandomClass ut;
ut.UNITTEST_setMState(1);
ut.wrapperProtectedFunction();
int res = ut.UNITTEST_getMState();
ASSERT_EQ(res, 2);
}
I seem to be doing something wrong, as the mState still appears to be private and thus I'm getting an inaccessible error. I've also tried calling it directly by just returning mState, but the same error applies.
One solution would be to move the mState to protected, but as there are other classes which inherit the RandomClass, I do not think that would be a save solution.
So how would I be able to solve such an issue and resolve my errors?
For future viewers here is the working code:
class RandomClass
{
public:
RandomClass()
{
mState = 0;
}
void publicFunction();
protected:
void protectedFunction()
{
++mState;
}
private:
int mState;
friend class UnittestRandomClass;
};
class UnittestRandomClass : public RandomClass
{
public:
void wrapperProtectedFunction()
{
protectedFunction();
}
void setMState(int state)
{
mState = state;
}
int getMState()
{
return mState;
}
};
int main() {
UnittestRandomClass ut;
ut.setMState(1);
ut.wrapperProtectedFunction();
int res = ut.getMState();
ASSERT_EQ(res, 2);
}
Your class declares a free-standing function to be friend.
Your unit test uses a member function of a class, the class is not declared friend.
You can write friend class UnitTestRandomClass;
Specifically, what you want to do, make a member function of a future derived class a friend is not provided by the standard. There is no syntax for that.
i have annoying problem where i need to pointer cast pointer member
here is example
class GlobalInterface
{
public:
virtual void DoAction() = 0;
}
class ActionClass_A: public GlobalInterface
{
public:
ActionClass_A(){};
~ActionClass_A(){};
void DoAction() { ..... } ;
void DoSomeActionOnlyForA() { ..... } ;
}
class ActionClass_B: public GlobalInterface
{
public:
ActionClass_B(){};
~ActionClass_B(){};
void DoAction() { ..... } ;
void DoSomeActionOnlyForB() { ..... } ;
}
#include "GlobalInterface.h"
#include "ActionClass_A.h"
#include "ActionClass_B.h"
class GlobalContainer()
{
public:
GlobalContainer(GlobalInterface* _action)
{
pAction = _action;
}
GlobalInterface* getAction() { return pAction; };
private:
GlobalInterface* pAction;
}
// Main
GlobalContainer* pGlobalContainer = new GlobalContainer(new ActionClass_B());
// WHY i need this casting to get the ActionClass_B DoAction()???
((ActionClass_B*)pGlobalContainer->getAction())->DoSomeActionOnlyForA();
i just want to avoid this casting , and call it like this :
and it will know which implamention it should invoke based on the object type
pGlobalContainer->getAction()->DoSomeActionOnlyForA()
or
pGlobalContainer->getAction()->DoSomeActionOnlyForB()
The virtual function in the base class is private. It should work with a public function.
... and it will know which implamention it should invoke based on the
object type.
But you're not letting it decide what implementation it should invoke based on type, you're trying to make that decision yourself by calling DoSomeActionOnlyForA() or DoSomeActionOnlyForB() directly.
This doesn't work because at the moment of the call the static type of the object is GlobalInterface* and the GlobalInterface class doesn't have member functions named like that.
The way to achieve what you want, let each derived class have it's own behavior, is to understand and use virtual functions correctly. For example you could do this:
class GlobalInterface
{
public:
virtual ~GlobalInterface() {}
virtual void DoAction() = 0;
};
class ActionClass_A: public GlobalInterface
{
public:
ActionClass_A() {}
~ActionClass_A() {}
void DoAction()
{
DoSomeActionOnlyForA(); // call specific action for A
}
void DoSomeActionOnlyForA() { /* implement specific action for A */ } ;
};
class ActionClass_B: public GlobalInterface
{
public:
ActionClass_B() {}
~ActionClass_B() {}
void DoAction()
{
DoSomeActionOnlyForB(); // call specific action for B
}
void DoSomeActionOnlyForB() { /* implement specific action for B */ } ;
};
As you can see, you have a virtual function DoAction() that is overridden in each of the derived classes to call the appropriate functionality for that class.
Then you can use it like this:
GlobalContainer* pGlobalContainer = new GlobalContainer(new ActionClass_B());
pGlobalContainer->getAction()->DoAction();
This will call ActionClass_B::DoAction() which in turn calls ActionClass_B::DoSomeActionOnlyForB().
If you instead create the container like this:
GlobalContainer* pGlobalContainer = new GlobalContainer(new ActionClass_A());
then the same call pGlobalContainer->getAction()->DoAction(); will instead call ActionClass_A::DoAction() which in turn calls the appropriate functionality for A.
As you can see, in this case it does indeed call the appropriate function based on the dynamic type of the object (DoAction() from A or from B).
For our project we are given a code snippet that we should NOT EDIT in any way. We are only allowed to write function definitions for the prototypes in the said snippet.
My problem and question is regarding how I should call the private functions when the code is written this way:
class ClassOne {
private:
void methodOne();
public:
void methodTwo();
};
So I should be able to access methodOne through methodTwo but without writing { methodTwo();} beside methodOne. Help me please?
You already have your class:
class ClassOne {
private:
void methodOne();
public:
void methodTwo();
};
Implement the functions of your class:
void ClassOne::methodOne() { // <-- private
// other code
}
void ClassOne::methodTwo() { // <-- public
// other code
methodOne(); // <-- private function called here
}
The class definition declares the member functions methodOne and methodTwo but does not define them. You need to define them out-of-class.
// I assume the return type is void since you omitted it, but
// keep in mind the compiler will not allow you to omit it!
void ClassOne::methodOne() {
// ...
}
void ClassOne::methodTwo() {
// ...
methodOne(); // OK since access is from a member of ClassOne
// ...
}
The private function is only private to things outside the object.
You can call m1 in m2 normally, like any other function.
To call methodOne from methodTwo just define method2 as:
void ClassOne::methodTwo() {
methodOne();
}
All private functions and variables are accessible from public functions. So you can call your private function as follows:
void ClassOne::methodTwo(){
methodOne();
}