accessing protected function from another class c++ - c++

I am trying to access a protected function in class Test but I have no idea how to do it.
Ok I admit one fact that I'm asking this because there's one part of my homework which I am tasked to put a function as protected: and access it instead of putting it to public:
and I am not sure how should I do it.
the code below is how I normally access a function but of course, it doesn't work since it's protected:
Test.h
#ifndef Test_Test_h
#define Test_Test_h
class Test {
protected:
void sampleOutputMethod();
};
#endif
Test.cpp
#include "Test.h"
void Test::sampleOutputMethod() {
std::cout << "this is a test output method" << std::endl;
}
main.cpp
#include Test.h
#include<iostream>
int main() {
Test test;
test.sampleOutputMethod();
}

There are essentially two ways of accessing a protected member:
1) Create a class that inherits from your class Test:
class Test2 : public Test {
public:
void sampleOutputMethod() { ::sampleOutputMethod; }
}
2) Create another class, and modify class Test to make the other class a friend of your Test class:
class Test; // Forward declaration of Test
class Test2 {
public:
void output( Test& foo ) { foo.sampleOutputMethod(); }
}
class Test {
protected:
void sampleOutputMethod();
}

A protected function is just as good as private function if you try to access it from a class that is not part of your hierarchy. You either have to make the class trying to access it a subclass of Test, or you have to declare it as friend class. I bet you need the first option.

You can delegate the function as well. Create a public function that calls the protected one.
This can be accomplished through either deriving Test or creating another class, Test2, and declaring Test a friend of Test2 and having Test2 contain an instance of Test.
Seeing all the instructions of your homework would help.

If you are allowed to modify class Test, you can add a public function which calls "sampleOutputMethod", or you can return function pointer of "sampleOutputMethod" using this trick https://stackoverflow.com/a/6538304/1784418

Related

Exposing only a single method of a class to another class but having it inaccessible everywhere else [duplicate]

Suppose I have three C++ classes FooA, FooB and FooC.
FooA has an member function named Hello, I want to call this function in class FooB, but I don't want class FooC be able to call it. The best way I can figure out to realize this is to declare FooB as a friend class of FooA. But as long as I do this, all FooA's private and protected members will be exposed which is quite unacceptable to me.
So, I wanna know if there is any mechanism in C++(03 or 11) better than friend class which can solve this dilemma.
And I assume it will be nice if the following syntax is possible:
class FooA
{
private friend class FooB:
void Hello();
void Hello2();
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello() // right
objA.Hello2() // right
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
I think you can use Attorney-Client here.
In your case example should be like this
class FooA
{
private:
void Hello();
void Hello2();
void Hello3();
int m_iData;
friend class Client;
};
class Client
{
private:
static void Hello(FooA& obj)
{
obj.Hello();
}
static void Hello2(FooA& obj)
{
obj.Hello2();
}
friend class FooB;
};
class FooB
{
void fun()
{
FooA objA;
Client::Hello(objA); // right
Client::Hello2(objA); // right
//objA.Hello3() // compile error
//ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
/*FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error*/
}
};
There's nothing to make a class a friend of one specific function, but you can make FooB a friend of a "key" class with private constructor, and then have FooA::Hello take that class as an ignored parameter. FooC will be unable to provide the parameter and hence can't call Hello:
Is this key-oriented access-protection pattern a known idiom?
You can partially expose a class's interfaces to a specified client by inherit it from an interface class.
class FooA_for_FooB
{
public:
virtual void Hello() = 0;
virtual void Hello2() = 0;
};
class FooA : public FooA_for_FooB
{
private: /* make them private */
void Hello() override;
void Hello2() override;
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
FooA_for_FooB &r = objA;
r.Hello() // right
r.Hello2() // right
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
Here access control is enhanced by the base class FooA_for_FooB. By a reference of type FooA_for_FooB, FooB can access the members defined within FooA_for_FooB. However, FooC cannot access those members since they have been override as private members in FooA. Your purpose can be achieved by not using the type FooA_for_FooB within FooC, or any other places except FooB, which can be kept without paying much attention.
This approach needs no friend, making things simple.
A similar thing can be done by making everything private in a base class, and selectively wrap-and-expose some of the members as public in the derived class. This approach may sometimes require ugly downcast, though. (Because the base class will become the "currency" among the whole program.)
No, and this is not really a limitation. To my mind, the limitation is that friend — a blunt weapon for hacking around design flaws — exists in the first place.
Your class FooA has no business knowing about FooB and FooC and "which one should be able to use it". It should have a public interface, and not care who can use it. That's the point of the interface! Calling functions within that interface should always leave the FooA in a nice, safe, happy, consistent state.
And if your concern is that you might accidentally use the FooA interface from somewhere you didn't mean to, well, simply don't do that; C++ is not a language suited to protecting against these kinds of user errors. Your test coverage should suffice in this case.
Strictly speaking, I'm sure you can obtain the functionality you're after with some ghastly complicated "design pattern" but, honestly, I wouldn't bother.
If this is a problem for the semantics of your program's design, then I politely suggest that your design has a flaw.
The safest solution is to use another class as the "go-between" for your two classes, rather than make one of them a friend. One way to do this is suggested in the answer by #ForEveR, but you can also do some searching about proxy classes and other design patterns that can apply.
You'll need inheritance. Try this:
// _ClassA.h
class _ClassA
{
friend class ClassA;
private:
//all your private methods here, accessible only from ClassA and _ClassA.
}
// ClassA.h
class ClassA: _ClassA
{
friend class ClassB;
private:
//all_your_methods
}
This way you have:
ClassB is the only one to be able to use ClassA.
ClassB cannot access _ClassA methods, that are private.
The whole idea of friend is to expose your class to a friend.
There are 2 ways you could be more specific about what you expose:
Inherit from FooA, that way only protected and public methods are exposed.
Only befriend a certain method, that way only that method will have access:
.
friend void FooB::fun();
You can hide private members in a base class, and then make FooA a child and friend of that base class (very touching).
// allows us to hide private members from friends of FooA,
// but still allows FooA itself to access them.
class PrivateFooA
{
private:
friend class FooA;
// only allow FooA to derive from this class
PrivateFooA() {};
// hidden from friends of FooA
void Hello3();
int m_iData;
};
// this class hides some of its private members from friend classes
class FooA : public PrivateFooA
{
private:
// give FooB access to private methods
friend class FooB;
void Hello();
void Hello2();
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello(); // right
objA.Hello2(); // right
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello(); // compile error
objA.Hello2(); // compile error
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
Anything you want to hide from FooB can be put into PrivateFooA (must be a private member), and everything else can be put directly into FooA. FooA will be able to access everything in PrivateFooA just like its own members.
This is more of an expansion of user3737631's answer, but I think it's worth posting because it includes the classes from the OP, the private constructor in PrivateFooA, and some additional comments that I thought would be helpful.
I had to do this recently and I didn't like the way these solutions leave a class type dangling around in the current namespace with essentially no purpose. If you REALLY do just want this functionality available to a single class then I would use a different pattern than those mentioned.
class Safety {
protected:
std::string _Text="";
public:
Safety(const std::string& initial_text) {
_Text=initial_text;
}
void Print(const std::string& test) {
std::cout<<test<<" Value: "<<_Text<<std::endl;
}
};
class SafetyManager {
protected:
// Use a nested class to provide any additional functionality to
// Safety that you want with protected level access. By declaring
// it here this code only belongs to this class. Also, this method
// doesn't require Safety to inherit from anything so you're only
// adding weight for the functionality you need when you need it.
// You need to be careful about how this class handles this object
// since it is really a Safety cast to a _Safety. You can't really
// add member data to this class but static data is ok.
class _Safety : Safety {
public:
void SetSafetyText(const std::string& new_text) {
_Text=std::string(new_text);
}
};
public:
static void SetSafetyText(Safety* obj, const std::string& new_text) {
if(obj==nullptr) throw "Bad pointer.";
_Safety& iobj=*(_Safety*)obj;
iobj.SetSafetyText(new_text);
}
};
Then in main (or anywhere else) you can't modify _Text through Safety but you can through SafetyManager (or it's descendants).
#include "Safety.h"
int main() {
Safety t("Hello World!");
t.Print("Initial");
SafetyManager::SetSafetyText(&t, "Brave New World!");
t.Print("Modified");
/*
t._Text; // not accessible
Safety::SetSafetyText(&t, "ERR");// doesn't exist
t.SetSafetyText(&t, "ERR"); // doesn't exist
_Safety _safety; // not accessible
SafetyManager::_Safety _safety; // not accessible
*/
}
Some would say that this follows better OOP practices than a friend class because it encapsulates the messy parts a little better and doesn't pass anything down the Safety chain of inheritance. You also don't need to modify the Safety class at all for this technique making it much more modular. These are probably the reasons why many newer languages allow for nested classes but almost nothing else has borrowed the friend concept even though this just adds functionality that is available only to a single class (and doesn't work if Safety is marked final or marked vital parts of it's code as private).

How to use mocks with a test fixture in GMock?

I have a test fixture in my tests so I don't have to instantiate objects of my class repeatedly, but I'm not sure how to use mocks with it. To put it simply, this is how the class is defined:
class Class1 {
public:
Class1(std::shared_ptr<Class2> class_two);
void doThisThing() { doThatThing(); }
}
class Class2 {
public:
Class2(Class3* class3_ptr);
int doThatThing();
}
(class 1 is constructed using a shared pointer to class 2. Class 2 is constructed with a pointer to class 3. Class 1 calls on a function "doThisThing" which calls Class 2's function doThatThing.)
I need to create a mock for doThatThing() (and the rest of Class2's functions), but can't figure out how to pass the mock object to Class 1. Here is what I have so far in my testing code:
class TestClass1 : public ::testing::Test {
TestClass1(){
//Construct instance of Class1 and store as member variable
std::shared_ptr<Class3> class_three = std::make_shared<Class3>();
std::shared_ptr<Class2> class_two = std::make_shared<Class2>((Class3*)class_three.get());
class_one = new Class1(class_two);
};
Class1* class_one;
}
MockClass2 : public Class2 {
MOCK_METHOD0(doThatThing, int());
}
TEST_F(TestClass1, doThatThingTest){
MockClass2 mockObj;
**THIS IS WHERE I'M STUCK. How do I get that mockObj into my TestClass1 Fixture? As of now, it is calling the actual function, not the mock***
class_one->doThatThing();
EXPECT_CALL(mockObj, doThatThing());
}
I had to abstract and simplify the actual code, so I hope the above makes sense.
Assuming that your MockClass2 works, you should try something like the following:
Here you should override the functions SetUp that is called right before every call of a test function to prepare your test data. And override TearDown that is called after every call of a test function to clean up test data.
struct TestClass1 : public ::testing::Test
{
void SetUp() override
{
class_two_mock = std::make_shared<MockClass2>();
class_one = std::make_unique<Class1>(class_two_mock);
}
void TearDown() override
{
class_one.reset();
class_two_mock.reset();
}
std::shared_ptr<MockClass2> class_two_mock
std::unique_ptr<Class1> class_one;
};
In the test function you must declare your expectations before something is executed.
TEST_F(TestClass1, doThatThingTest)
{
EXPECT_CALL(*class_two_mock, doThatThing());
class_one->doThatThing();
}
You may need an interface for Class2. The code here is not tested.

What are the possible ways to test private methods with a parameterised unit test with Google test API for C++?

I'm using Google Test api to unit test C++ code.
with google test API sample, i see there is a option to test the private methods with FRIEND_TEST macro. Also i see TEST_P,INSTANTIATE_TEST_CASE_P macros for parameterized tests.
So i tried below logic to implement parameterised unit test for private method. But i got an error with 'Foo::Bar' : cannot access private member declared in class 'Foo'. when i try to use the class FRIEND_TEST_Test3 to test with parameterized test macro TEST_P.
So please let me know the possible ways to test private method with parameterised unit test with Google test macros.
class Foo {
public:
Foo() {}
private:
int Bar() const { return 1; }
FRIEND_TEST(FRIEND_TEST_Test, TEST);
FRIEND_TEST(FRIEND_TEST_Test2, TEST_F);
FRIEND_TEST(FRIEND_TEST_Test3, TEST_P);
};
TEST(FRIEND_TEST_Test, TEST) {
ASSERT_EQ(1, Foo().Bar());
}
class FRIEND_TEST_Test2 : public ::testing::Test {
public:
Foo foo;
};
TEST_F(FRIEND_TEST_Test2, TEST_F) {
ASSERT_EQ(1, foo.Bar());
}
class CodeLocationForTESTP : public ::testing::TestWithParam<int> {
};
INSTANTIATE_TEST_CASE_P(, CodeLocationForTESTP, ::testing::Values(0,1,2,1,0));
TEST_P(CodeLocationForTESTP, Verify) {
ASSERT_TRUE(0==GetParam());
}
class FRIEND_TEST_Test3 : public ::testing::Test,public ::testing::TestWithParam<int> {
public:
Foo foo;
};
INSTANTIATE_TEST_CASE_P(, FRIEND_TEST_Test3, ::testing::Values(0,1,2,1,0));
TEST_P(FRIEND_TEST_Test3, Verify) {
ASSERT_EQ(1, foo.Bar());
}
As stated in the googletest document, the second argument of FRIEND_TEST must be the test name which we want to execute.
Since your 3rd unit test is TEST_P(FRIEND_TEST_Test3, Verify) and its test name is Verify, not TEST_P, you have to define FRIEND_TEST(FRIEND_TEST_Test3, Verify) in the private scope of Foo.
In addition, since ::testing::Test is a base class of ::testing::TestWithParam, we don't need to explicitly inherit ::testing::Test to FRIEND_TEST_Test3.
Thus the following code would well work for you:
#include <gtest/gtest.h>
#include <gtest/gtest_prod.h>
class Foo
{
public:
Foo() {}
private:
int Bar() const { return 1; }
FRIEND_TEST(FRIEND_TEST_Test3, Verify);
// ^^^^^^ not TEST_P
};
class FRIEND_TEST_Test3 : public ::testing::TestWithParam<int>
{
public:
Foo foo;
};
INSTANTIATE_TEST_CASE_P(, FRIEND_TEST_Test3, ::testing::Values(0,1,2,1,0));
TEST_P(FRIEND_TEST_Test3, Verify)
{
ASSERT_EQ(1, foo.Bar());
}
Move your test to a own File (for instance test.cpp). This file is only allowed to contain test an no productive code. Now add #define private public at to - now you can access the private members without introducing strange getters, freinds or whatever in your test.
The C++ Standard says that this results in undefined behavior (Define private to public in C++) but it never made any problem to me.
I think it is not a good practice to modify our code to make it testable

Call a method of a different class in base class method

#include <iostream>
using namespace std;
//can't modify it
class Orig{
public:
void Method(){
cout << "I am original method";
}
};
class Mock{
public:
void Method(){
cout << "I am mock method";
}
};
//can't modify it
class UseMethod{
Orig object;
public:
void UseOrigMethod(){
object.Method();
}
};
class UseMethodMock : public UseMethod{
//some code
};
int main()
{
UseMethodMock o;
o.UseOrigMethod();
}
I want to call Method() of Mock class using above code when I call o.UseOrigMethod(); from main. I have tried declaring object of Mock class in UseMethodMock but still it uses Orig's object.
Is there any way we can fool compiler and call Mock's Method when it calls object.Method() in UseMethod class?
I can change code in Mock and UseMethodMock classes but not in others.
There is no shame in modifying code to make it more testable, so maybe you can reconsider. In this case:
Prepare Orig for inheritance by making its methods virtual.
Inject an Orig instance into UseMethod via its constructor (beware slicing – pass by pointer or reference).
Have Mock inherit from Orig and override the virtual methods.
If the performance of virtual calls is a concern, do it all at compile time:
Make UseMethod a template, that takes the type of Orig as a template parameter.
In production code, use UseMethod<Orig>.
In test code, use UseMethod<Mock>.
If you really, absolutely, positively can definitely, certainly not modify Orig and UseMethod, you can abuse the preprocessor:
#include "Orig.h"
#define Orig Mock
#include "UseMethod.h"
#undef Orig
Of course, this comes with a whole boatload of caveats (most notably, it assumes that UseMethod.cpp does not refer explicitly to the Orig type), and in general I would strongly advise against it.
Because you call orig's method. You should override useOrigMethod() in UseMethodMock class.
you just need to change the UseMethod class Orig object to Moke object i will give expected output it means called the method of Moke class.
code:
#include <iostream>
using namespace std;
//can't modify it
class Orig{
public:
void Method(){
cout << "I am original method";
}
};
class Mock{
public:
void Method(){
cout << "I am mock method";
}
};
//can't modify it
class UseMethod{
//need to change here Orig to Moke
Mock object;
public:
void UseOrigMethod(){
object.Method();
}
};
class UseMethodMock : public UseMethod{
//some code
};
int main()
{
UseMethodMock o;
o.UseOrigMethod();
}
output
I am mock method
--------------------------------
Process exited after 0.006435 seconds with return value 0
Press any key to continue . . .

Allowing a "friend" class to access only some private members

Suppose I have three C++ classes FooA, FooB and FooC.
FooA has an member function named Hello, I want to call this function in class FooB, but I don't want class FooC be able to call it. The best way I can figure out to realize this is to declare FooB as a friend class of FooA. But as long as I do this, all FooA's private and protected members will be exposed which is quite unacceptable to me.
So, I wanna know if there is any mechanism in C++(03 or 11) better than friend class which can solve this dilemma.
And I assume it will be nice if the following syntax is possible:
class FooA
{
private friend class FooB:
void Hello();
void Hello2();
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello() // right
objA.Hello2() // right
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
I think you can use Attorney-Client here.
In your case example should be like this
class FooA
{
private:
void Hello();
void Hello2();
void Hello3();
int m_iData;
friend class Client;
};
class Client
{
private:
static void Hello(FooA& obj)
{
obj.Hello();
}
static void Hello2(FooA& obj)
{
obj.Hello2();
}
friend class FooB;
};
class FooB
{
void fun()
{
FooA objA;
Client::Hello(objA); // right
Client::Hello2(objA); // right
//objA.Hello3() // compile error
//ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
/*FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error*/
}
};
There's nothing to make a class a friend of one specific function, but you can make FooB a friend of a "key" class with private constructor, and then have FooA::Hello take that class as an ignored parameter. FooC will be unable to provide the parameter and hence can't call Hello:
Is this key-oriented access-protection pattern a known idiom?
You can partially expose a class's interfaces to a specified client by inherit it from an interface class.
class FooA_for_FooB
{
public:
virtual void Hello() = 0;
virtual void Hello2() = 0;
};
class FooA : public FooA_for_FooB
{
private: /* make them private */
void Hello() override;
void Hello2() override;
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
FooA_for_FooB &r = objA;
r.Hello() // right
r.Hello2() // right
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
Here access control is enhanced by the base class FooA_for_FooB. By a reference of type FooA_for_FooB, FooB can access the members defined within FooA_for_FooB. However, FooC cannot access those members since they have been override as private members in FooA. Your purpose can be achieved by not using the type FooA_for_FooB within FooC, or any other places except FooB, which can be kept without paying much attention.
This approach needs no friend, making things simple.
A similar thing can be done by making everything private in a base class, and selectively wrap-and-expose some of the members as public in the derived class. This approach may sometimes require ugly downcast, though. (Because the base class will become the "currency" among the whole program.)
No, and this is not really a limitation. To my mind, the limitation is that friend — a blunt weapon for hacking around design flaws — exists in the first place.
Your class FooA has no business knowing about FooB and FooC and "which one should be able to use it". It should have a public interface, and not care who can use it. That's the point of the interface! Calling functions within that interface should always leave the FooA in a nice, safe, happy, consistent state.
And if your concern is that you might accidentally use the FooA interface from somewhere you didn't mean to, well, simply don't do that; C++ is not a language suited to protecting against these kinds of user errors. Your test coverage should suffice in this case.
Strictly speaking, I'm sure you can obtain the functionality you're after with some ghastly complicated "design pattern" but, honestly, I wouldn't bother.
If this is a problem for the semantics of your program's design, then I politely suggest that your design has a flaw.
The safest solution is to use another class as the "go-between" for your two classes, rather than make one of them a friend. One way to do this is suggested in the answer by #ForEveR, but you can also do some searching about proxy classes and other design patterns that can apply.
You'll need inheritance. Try this:
// _ClassA.h
class _ClassA
{
friend class ClassA;
private:
//all your private methods here, accessible only from ClassA and _ClassA.
}
// ClassA.h
class ClassA: _ClassA
{
friend class ClassB;
private:
//all_your_methods
}
This way you have:
ClassB is the only one to be able to use ClassA.
ClassB cannot access _ClassA methods, that are private.
The whole idea of friend is to expose your class to a friend.
There are 2 ways you could be more specific about what you expose:
Inherit from FooA, that way only protected and public methods are exposed.
Only befriend a certain method, that way only that method will have access:
.
friend void FooB::fun();
You can hide private members in a base class, and then make FooA a child and friend of that base class (very touching).
// allows us to hide private members from friends of FooA,
// but still allows FooA itself to access them.
class PrivateFooA
{
private:
friend class FooA;
// only allow FooA to derive from this class
PrivateFooA() {};
// hidden from friends of FooA
void Hello3();
int m_iData;
};
// this class hides some of its private members from friend classes
class FooA : public PrivateFooA
{
private:
// give FooB access to private methods
friend class FooB;
void Hello();
void Hello2();
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello(); // right
objA.Hello2(); // right
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello(); // compile error
objA.Hello2(); // compile error
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
Anything you want to hide from FooB can be put into PrivateFooA (must be a private member), and everything else can be put directly into FooA. FooA will be able to access everything in PrivateFooA just like its own members.
This is more of an expansion of user3737631's answer, but I think it's worth posting because it includes the classes from the OP, the private constructor in PrivateFooA, and some additional comments that I thought would be helpful.
I had to do this recently and I didn't like the way these solutions leave a class type dangling around in the current namespace with essentially no purpose. If you REALLY do just want this functionality available to a single class then I would use a different pattern than those mentioned.
class Safety {
protected:
std::string _Text="";
public:
Safety(const std::string& initial_text) {
_Text=initial_text;
}
void Print(const std::string& test) {
std::cout<<test<<" Value: "<<_Text<<std::endl;
}
};
class SafetyManager {
protected:
// Use a nested class to provide any additional functionality to
// Safety that you want with protected level access. By declaring
// it here this code only belongs to this class. Also, this method
// doesn't require Safety to inherit from anything so you're only
// adding weight for the functionality you need when you need it.
// You need to be careful about how this class handles this object
// since it is really a Safety cast to a _Safety. You can't really
// add member data to this class but static data is ok.
class _Safety : Safety {
public:
void SetSafetyText(const std::string& new_text) {
_Text=std::string(new_text);
}
};
public:
static void SetSafetyText(Safety* obj, const std::string& new_text) {
if(obj==nullptr) throw "Bad pointer.";
_Safety& iobj=*(_Safety*)obj;
iobj.SetSafetyText(new_text);
}
};
Then in main (or anywhere else) you can't modify _Text through Safety but you can through SafetyManager (or it's descendants).
#include "Safety.h"
int main() {
Safety t("Hello World!");
t.Print("Initial");
SafetyManager::SetSafetyText(&t, "Brave New World!");
t.Print("Modified");
/*
t._Text; // not accessible
Safety::SetSafetyText(&t, "ERR");// doesn't exist
t.SetSafetyText(&t, "ERR"); // doesn't exist
_Safety _safety; // not accessible
SafetyManager::_Safety _safety; // not accessible
*/
}
Some would say that this follows better OOP practices than a friend class because it encapsulates the messy parts a little better and doesn't pass anything down the Safety chain of inheritance. You also don't need to modify the Safety class at all for this technique making it much more modular. These are probably the reasons why many newer languages allow for nested classes but almost nothing else has borrowed the friend concept even though this just adds functionality that is available only to a single class (and doesn't work if Safety is marked final or marked vital parts of it's code as private).