Calling private member of inherited class for unittest - c++

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.

Related

Supporting custom hooks in existing cpp class

I am designing support for custom hooks in existing C++ class.
class NotMyClass {
public:
void DoSomething() {
// Needs custom logic here.
hook_.DoSomethingCustom();
}
protected:
Hook hook_;
int not_my_class_inner_variable_1_;
Node not_my_class_inner_variable_2_;
...... More Class vars.....
}
class Hook {
public:
void DoSomethingCustom() {
// Some custom logic that needs to access not_my_class_inner_variable_1_, not_my_class_inner_variable_2 etc. .
}
}
Adding some more context here after initial comments: NotMyClass class is autogenerated and no custom logic can be added to this class. We want to be able to add custom hooks inside the autogenerated classes. So the plan was to instead pass/ingect in a Hook class that will be able to provide some custom processing. The autogenerated NotMyClass class will have hook_. DoSomethingCustom().
What's the best way to access NotMyClass member variables inside Hook ?
I don't want to change the class structure(that is use inheritence) of NotMyClass due to additional constraints.
Is making Hook a friend of NotMyClass a good option and then passing NotMyClass as this to Hook functions ?
Thanks in advance!
The problem cannot be solved as stated, i.e., without breaking the Open-Closed-Principle (OCP), which says that "classes (and other things) should be open for extension but closed for modification." In this case, this means that you shouldn't try to both (a) leave MyClass unchanged and (b) access its private or protected members from outside. Private (or protected) signal things that are not accessed from the outside, that's literally what private (or protected) are designed for. You can circumvent this (old ways, new ways) but you shouldn't.
The answer by sanitizedUser modifies MyClass, which is undesirable as per the question. A hacky but straight-forward suggestion to your problem might be to pass the fields to be modified explicitly to the method by reference:
class MyClass {
public:
void DoSomething() {
// Pass references to the fields you want to modify.
hook_.DoSomethingCustom(my_class_inner_variable_1_, my_class_inner_variable_2_);
}
protected:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
}
class Hook {
public:
void DoSomethingCustom(int &inner_variable_1, Node& inner_variable_2_) {
// Use the data members.
}
}
To signal that your Hook class explicitly is allowed to access members of MyClass, you could declare it as a friend. Example:
#include <iostream>
class Node {};
class MyClass;
class Hook {
public:
void DoSomethingCustom(MyClass &m);
};
class MyClass {
friend Hook; // Allows the Hook class to access our members!
public:
MyClass(Hook h): hook_(h) {}
void DoSomething() {
// Pass references to the fields you want to modify.
hook_.DoSomethingCustom(*this);
}
void print_my_class_inner_variable_1_() {
std::cout << my_class_inner_variable_1_ << std::endl;
}
protected:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
};
void Hook::DoSomethingCustom(MyClass &m) {
// Allowed to access private member because we are a friend!
m.my_class_inner_variable_1_ = 42;
}
int main() {
MyClass c{Hook{}};
c.print_my_class_inner_variable_1_();
c.DoSomething();
c.print_my_class_inner_variable_1_();
}
Note: your whole design with this "Hook" looks very weird to me. How do you "add hooks" to this thing (which imho is one of the defining requirements for calling something a "hook")? I'm sure if you posted a lot more context, people here would suggest a very different larger-scale design.
It's not an ideal solution but if you are allowed to declare the Hook class a friend of NotMyClass then the following code somewhat works.
#include <iostream>
class NotMyClass;
class Hook {
public:
void DoSomethingCustom(const NotMyClass& c);
};
class NotMyClass {
friend Hook;
public:
void DoSomething() {
hook_.DoSomethingCustom(*this);
}
protected:
Hook hook_;
int not_my_class_inner_variable_1_;
// Commenting Node member out because the definition of it is missing.
// Node not_my_class_inner_variable_2_;
};
void Hook::DoSomethingCustom(const NotMyClass& c) {
std::cout << c.not_my_class_inner_variable_1_ << '\n';
}
int main() {
NotMyClass{}.DoSomething();
return 0;
}
Output.
0
If you can modify NotMyClass entirely then I advice you to use polymorphism and declare Hook as an abstract class. This way its behaviour can be swapped more easily.
#include <iostream>
#include <string>
template<class State>
struct Hook {
virtual State run(const State& s) const = 0;
};
struct ExampleState {
int number;
std::string text;
};
std::ostream& operator<<(std::ostream& stream, const ExampleState& state) {
stream << state.number << ", " << state.text << '\n';
return stream;
}
struct ExampleHook : public Hook<ExampleState> {
ExampleState run(const ExampleState& s) const override;
};
class Receiver {
public:
void DoSomething();
Receiver(const Hook<ExampleState>* const hook);
private:
const Hook<ExampleState>* const hook;
ExampleState state;
};
ExampleState ExampleHook::run(const ExampleState& s) const {
// Returning a modified state.
return {
s.number + 1,
"Modified " + s.text
};
}
void Receiver::DoSomething() {
std::cout << "Original state:\n" << this->state;
this->state = this->hook->run(this->state);
std::cout << "Modified state:\n" << this->state;
}
Receiver::Receiver(const Hook<ExampleState>* const hook)
: hook(hook), state{0, "hello"} {}
int main() {
ExampleHook hook;
Receiver receiver(&hook);
receiver.DoSomething();
return 0;
}
Output.
Original state:
0, hello
Modified state:
1, Modified hello
One way of doing this is declaring data members of class MyClass public and then passing a reference to an instance of MyClass to an instance of Hook.
class MyClass {
public:
void DoSomething() {
// Pass a reference to this.
hook_.DoSomethingCustom(*this);
}
public:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
}
class Hook {
public:
void DoSomethingCustom(const MyClass& c) {
// Use the data members.
auto& ref1 = c.my_class_inner_variable_1_;
auto& ref2 = c.my_class_inner_variable_2_;
}
}
If you cannot declare the members public because this is a legacy code, then there is always the evil option.
#define protected public
// Your code.
#undef protected
However, if this code is already compiled as a dynamic library then you are out of luck.

How to create an interface to allow for the construction of different nested derived classes in C++?

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).

Is there a way in C++ to restrict a function of a given class to another class only(without using inheritance, friend)?

I want to design a class having a function which should be restricted to be called from another class only. Specifically, in the given code
class Club
{
int id;
string name;
vector<string> members;
int generateId()
{
static int i=1;
return i++;
}
public:
Club(string name) { this->name = name; this->id = generateId(); }
void registerMember(string memberName) { members.push_back(memberName); }
int getId() { return id; }
};
class Application
{
vector<Club> clubs;
public:
void registerClub(Club &club) { clubs.push_back(club); }
void addMemberToClub(int clubId, string memberName)
{
for(Club club: clubs)
{
if(clubId == club.getId())
club.registerMember(memberName);
}
}
};
An user(public user) can create an object of the class Club and register using the function registerMember() since it's public. I want the user to register via an object of the class Application, using the addMemberToClub() function only. If the user goes by the former way mentioned, I can't keep track of the user. Is there a way to enforce the latter?
I don't want to use the access modifier protected since inheritance has no meaning here.
I don't want to use the friend keyword, since it's considered bad practice.
Here is a "lock-and-key" way to permit another class (and only that class) or even a single function in another class to access just one member function, unlike friend which exposes all private members at the same time:
#include <iostream>
class Key;
class Locked
{
static const char* const Greeting;
public:
static Key secretive();
static void attacker();
};
struct Admin
{
void doit();
};
class Key
{
~Key() = default;
//friend class Admin;
friend void Admin::doit();
friend Key Locked::secretive();
};
void Admin::doit()
{
Locked::secretive();
std::cout << Locked::Greeting; // compile error
}
constexpr const char* Locked::Greeting = "Hello!\n";
Key Locked::secretive()
{
std::cout << Greeting;
return Key();
}
void Locked::attacker()
{
std::cout << Locked::Greeting; // ok, it's just private
Locked::secretive(); // compile error, it's locked down tight
}
int main()
{
Admin a;
a.doit();
std::cout << Locked::Greeting; // compile error
Locked::secretive(); // compile error
}
It also works around the "which class is declared first?" problem that prevents two classes from mutually friending individual member functions of each other, because the restricted operation needs to follow only a forward declaration of the key type; the full definition of the other type can (and in this example does) appear above the key definition, allowing individual members to be named in the key type's friend directive.
Note that in this solution the "obvious" fact that other members of the same class can access the locked function is NOT true. The compiler prevents Locked::attacker() from calling Locked::secretive().
Note also that I've used static in this example to minimize the number of objects I had to create, but the approach works just fine for non-static member functions too.
A potentially MUCH easier way to restrict what part of the program can call your protected function is with a simple flag:
class Application
{
static bool addingMember = 0;
public:
static bool isRegistrationOk() { return addingMember; }
void registerClub(Club &club) { clubs.push_back(club); }
void addMemberToClub(int clubId, string memberName)
{
addingMember = true;
for(Club club: clubs)
{
if(clubId == club.getId())
club.registerMember(memberName);
}
addingMember = false;
}
};
void Club::registerMember(string memberName)
{
assert(Application::isRegistrationOk());
members.push_back(memberName);
}
Much easier to grok, but it's a runtime check not compile-time, and requires additional work to be made thread-safe. But it accomplishes the goal with no usage of friend or inheritance.
friend is an appropriate mechanism to use in this case. Make registerMember private in Club, and Club can grant friendship to Application:
class Club
{
// ...
void registerMember(string memberName) { members.push_back(memberName); }
public:
// ...
friend class Application;
};
Now only Application can call registerMember, and Club as well, of course.
Here's a demo.

Calling the method of class with unidentified type

I have a class named MyClass that is subscribed by another class. When some events happen, MyClass should notify subscribers.
I'm trying to use template for the subscriber's type. Because I don't want to let others(who are in charge of subscriber class) need to care about modifying MyClass for subscribing.
So I've written codes below,
class MyClass {
public:
template<typename T>
void subscribeEvents(const T &controller)
{
m_subscriber = static_cast<T*>(m_subscriber);
m_subscriber = &controller;
}
void notifyPositionChanged(const long &position) const {
(m_subscriber)->onPositionChanged(position);
}
private:
void m_subscriber; // will be changed to array or something else
}
Actually the controller object has a method namedonPositionChanged.
But as you know, it's not compiled for this line.
(m_subscriber)->onPositionChanged(position);
Now I understand why it's an error, but the problem is that I don't know how to modify codes or change my design. Please let me know what I'm missing and misunderstanding. Thanks in advance.
You dont need to use template for this. Just use a base class for your subscribers. And MyClass operate on your base class
class ISubscribe {
public:
virtual void onPositionChanged(const long &position) = 0;
};
class MyClass {
public:
void subscribeEvents(ISubscribe *controller)
{
m_subscriber = controller;
}
void notifyPositionChanged(const long &position) const {
(m_subscriber)->onPositionChanged(position);
}
private:
ISubscribe *m_subscriber; // will be changed to array or something else
};
class SampleSubscriber : public ISubscribe {
public :
void onPositionChanged(const long &position) override{
...
}
};
void main() {
SampleSubscriber s;
MyClass m;
m.subscribeEvents(&s);
....
}
You need to define a common interface to all your subscribers, then use this interface as m_subscriber's type. Savagely casting whatever parameter you receive to a defined type will lead only to undefined behaviors.
Use std::function:
class MyClass {
public:
template<typename CALLBACK>
void subscribeEvents(CALLBACK &&controller)
{
m_subscriber = std::forward<CALLBACK>(controller);
}
void notifyPositionChanged(const long &position) const
{
if (m_subscriber)
m_subscriber(position);
}
private:
std::function<void(const long&)> m_subscriber;
}
This gives the subscriber full freedom of what it wants to subscribe. For example:
there.subscribeEvents([this](const long &pos) { handlePosChange(pos); }

Resolving a Forward Declaration Issue Involving a State Machine in C++

I've recently returned to C++ development after a hiatus, and have a question regarding
implementation of the State Design Pattern. I'm using the vanilla pattern, exactly as
per the GoF book.
My problem is that the state machine itself is based on some hardware used as part of
an embedded system - so the design is fixed and can't be changed. This results in a
circular dependency between two of the states (in particular), and I'm trying to
resolve this. Here's the simplified code (note that I tried to resolve this by using
headers as usual but still had problems - I've omitted them in this code snippet):
#include <iostream>
#include <memory>
using namespace std;
class Context
{
public:
friend class State;
Context() { }
private:
State* m_state;
};
class State
{
public:
State() { }
virtual void Trigger1() = 0;
virtual void Trigger2() = 0;
};
class LLT : public State
{
public:
LLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class ALL : public State
{
public:
ALL() { }
void Trigger1() { new LLT(); }
void Trigger2() { new DH(); }
};
// DL needs to 'know' about DH.
class DL : public State
{
public:
DL() { }
void Trigger1() { new ALL(); }
void Trigger2() { new DH(); }
};
class HLT : public State
{
public:
HLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class AHL : public State
{
public:
AHL() { }
void Trigger1() { new DH(); }
void Trigger2() { new HLT(); }
};
// DH needs to 'know' about DL.
class DH : public State
{
public:
DH () { }
void Trigger1() { new AHL(); }
void Trigger2() { new DL(); }
};
int main()
{
auto_ptr<LLT> llt (new LLT);
auto_ptr<ALL> all (new ALL);
auto_ptr<DL> dl (new DL);
auto_ptr<HLT> hlt (new HLT);
auto_ptr<AHL> ahl (new AHL);
auto_ptr<DH> dh (new DH);
return 0;
}
The problem is basically that in the State Pattern, state transitions are made by
invoking the the ChangeState method in the Context class, which invokes the
constructor of the next state.
Because of the circular dependency, I can't invoke the constructor because it's
not possible to pre-define both of the constructors of the 'problem' states.
I had a look at this article, and the template method which seemed to be the ideal solution - but it doesn't compile and my knowledge of templates is a rather limited...
The other idea I had is to try and introduce a Helper class to the subclassed states,
via multiple inheritance, to see if it's possible to specify the base class's constructor
and have a reference to the state subclasse's constructor. But I think that was rather
ambitious...
Finally, would a direct implmentation of the Factory Method Design Pattern be the best way
to resolve the entire problem?
You can define the member functions outside of the class definitions, e.g.,
class DL : public State
{
public:
void Trigger2();
};
inline void DL::Trigger2() { new DH(); }
Define the member functions that rely on later class definitions after those classes are defined. The inline keyword is only necessary if you define the member function outside of the class in the header file.
As an aside, why are you just using new DH() in your functions; you're leaking memory everywhere!