Specific "getter setter" dedicated object - c++

I'd like to create an object used to store data, restricting read/write access.
For example :
OBJ obj1;
OBJ obj2;
// DataOBJ has 2 methods : read() and write()
DataOBJ dataOBJ1 (obj1);
With the code above, I want obj1 to access write() method, while other OBJ objects (obj2 in this case) should only access the read() method.
Is it possible to create a DataOBJ class restricting rights like that ?
The classical "getter setter" does not suit my needs.
Thanks.

You can control access to write/read by template global reference obj1/obj2 like in this example:
class OBJ {
};
OBJ obj1;
OBJ obj2;
// RESTRICTED ACCESS
class DataOBJBase {
protected:
void write() {}
void read() {}
};
template <OBJ&>
class DataOBJ;
// ALLOW WRITE IF FOR obj1
template <>
class DataOBJ<obj1> : public DataOBJBase {
public:
using DataOBJBase::write;
};
// ALLOW READ IF FOR obj2
template <>
class DataOBJ<obj2> : public DataOBJBase {
public:
using DataOBJBase::read;
};
int main() {
DataOBJ<obj1> dobj1;
dobj1.write(); // cannot read
DataOBJ<obj2> dobj2;
dobj2.read(); // cannot write
}

I think your best bet is defining an interface for the read and write methods, and pass a read-only wrapper object (which implements write by throwing an exception) rather than the real object to anyone who should not get write permission.
Mind you, this does not stop malicious code from dissecting your wrapper object -- if you want to do that, the DataOBJ should live in a different process than the read-only clients, and the RPC mechanism at the process boundary needs to enforce the access permission.

You could do it with a set of different classes, with the "disabled" method throwing an exception.
Something like:
struct DataInterface
{
virtual void read(...) = 0;
virtual void write(...) = 0;
};
struct DataReadOnly : public DataInterface
{
void read(...) { ... }
void write(...) { throw write_not_allowed(); }
};
struct DataReadWrite : public DataInterface
{
void read(...) { ... }
void write(...) { ... }
};

A thought I have and is probably bad practice. Nevertheless, I'll answer the question as asked with something that came to mind:
Static variables.
class Foo
{
private:
int y;
public:
Foo();
~Foo();
void set(int);
int get(void);
};
Foo::Foo()
{
static int c = 0;
++c;
y = c;
}
Foo::~Foo()
{
--y;
}
int Foo::get(void )
{
if(y == 1)
return y;
else
//do return an error code or something
}
void Foo::set(int r)
{
if(y== 2)
y = r;
else
//Do nothing
}
int main()
{
Foo *x1 = new Foo(); //Gets assigned 1
Foo *x2 = new Foo(); //Gets assigned 2
return 0;
}
Edit: For clarification -- I left out the delete's, and what not as well as the logic for properly decrementing on the destruction as my answer is hashing an idea out there, versus coding for the OP.

Related

Crash when method of class is executing but smart pointer deleted the object

I faced a problem with C++ memory management and smart pointers.
I have a code to demonstrate you the problem:
#include <memory>
class Closeable
{
public:
virtual void Close() = 0;
};
class DisconnectionHandler
{
public:
virtual void HandleDisconnection() = 0;
};
class EventHandler
{
public:
virtual void HandleEvent() = 0;
};
class Notifier
{
public:
virtual void OnDisconnection() = 0;
};
class RemoteSystem : public Closeable
{
public:
void SetReceiveDataEventHandler(const std::shared_ptr<EventHandler>& receive_data_event_handler) {
this->receive_data_event_handler_ = receive_data_event_handler;
}
void Close() override { this->receive_data_event_handler_ = nullptr; }
// In this example to simplify the code I just call this method from the main function.
void OnDataReceived() { this->receive_data_event_handler_->HandleEvent(); }
private:
std::shared_ptr<EventHandler> receive_data_event_handler_;
};
class ReceiveDataEventHandler : public EventHandler
{
public:
explicit ReceiveDataEventHandler(const std::shared_ptr<DisconnectionHandler>& disconnection_handler)
: disconnection_handler_(disconnection_handler) {}
void HandleEvent() override {
// Some code of receiving data.
// But we can find out that connection was closed and we must call the disconnection handler.
if (this->IsConnectionClosed()) {
this->disconnection_handler_->HandleDisconnection();
return;
}
// Some other stuff..
}
private:
[[nodiscard]] bool IsConnectionClosed() const {
// In the example code I just return true.
return true;
}
private:
const std::shared_ptr<DisconnectionHandler> disconnection_handler_;
};
class RemoteSystemDisconnectionHandler : public DisconnectionHandler
{
public:
explicit RemoteSystemDisconnectionHandler(const std::shared_ptr<Closeable>& closeable_remote_system,
Notifier* notifier)
: closeable_remote_system_(closeable_remote_system), notifier_(notifier) {}
~RemoteSystemDisconnectionHandler() { printf("Destructed.\n"); }
void HandleDisconnection() override {
this->closeable_remote_system_->Close();
printf("Closed.\n");
this->notifier_->OnDisconnection();
printf("Notified.\n");
}
private:
const std::shared_ptr<Closeable> closeable_remote_system_;
Notifier* const notifier_;
};
class ClientNotifier : public Notifier
{
public:
void OnDisconnection() override { printf("Disconnected.\n"); }
};
int main() {
ClientNotifier notifier;
auto remote_system = std::make_shared<RemoteSystem>();
{
// Scope for losing references in the main function after SetReceiveDataEventHandler.
auto disconnection_handler = std::make_shared<RemoteSystemDisconnectionHandler>(remote_system, &notifier);
auto receive_data_event_handler = std::make_shared<ReceiveDataEventHandler>(disconnection_handler);
remote_system->SetReceiveDataEventHandler(receive_data_event_handler);
}
// Only in the example.
remote_system->OnDataReceived();
return 0;
}
You can also run this code. In this example program crashes on the line this->notifier_->OnDisconnection(). The output of the program:
Destructed.
Closed.
*crash*
This occurs because of losing the last reference to the ReceiveDataEventHandler when calling method RemoteSystem::Close from RemoteSystemDisconnectionHandler::HandleDisconnection, accordingly, losing the reference to the RemoteSystemDisconnectionHandler and deleting this object. After the Close method and deleting both objects of classes RemoteSystemDisconnectionHandler and ReceiveDataEventHandler it returns to the RemoteSystemDisconnectionHandler::HandleDisconnection method and prints 'Closed.' to the output, but since the object has been already deleted, the next line occurs an error, because now this is deleted and any access to it occurs memory exception.
I also tried to rewrite this code on Java and it works fine, unlike C++.
So, I want to ask you guys if there is a solution for this problem in the C++ community?
I thought C++ had no problems with memory management since smart pointers exist, but appearently I was wrong.
Hope for your help!
Thanks in advance!
A simple solution is to make a copy of the shared_ptr before invoking the method on it:
void OnDataReceived()
{
auto temp = this->receive_data_event_handler_;
if (temp)
{
temp->HandleEvent();
}
}
temp will keep the pointer alive until after the method invocation has completed.
However note that if you are using multiple threads in your real code, std::shared_ptr is not thread safe so you need to introduce a mutex to protect access to receive_data_event_handler_:
class RemoteSystem : public Closeable
{
public:
void SetReceiveDataEventHandler(const std::shared_ptr<EventHandler>& receive_data_event_handler) {
this->receive_data_event_handler_ = receive_data_event_handler;
}
void Close() override
{
std::unique_lock lock(mutex);
this->receive_data_event_handler_ = nullptr;
}
// In this example to simplify the code I just call this method from the main function.
void OnDataReceived()
{
std::shared_ptr<EventHandler> temp;
{
std::unique_lock lock(mutex);
temp = this->receive_data_event_handler_;
}
if (temp)
{
temp->HandleEvent();
}
}
private:
std::shared_ptr<EventHandler> receive_data_event_handler_;
std::mutex mutex;
};

How to ensure that a method is executed only once for the lifetime of that object?

class MyObj{
public:
void myFunc(){
//ToBeExecutedJustOnce
}
};
I have a function that I want to be executable only once for the lifetime of MyObj. There may be many instances of MyObj, and each should be able to execute that function once. So if I have:
MyObj first;
MyObj second;
MyObj third:
first.myFunc(); // Should execute
second.myFunc(); // Should execute
third.myFunc(); // Should execute
first.myFunc(); // Should not execute
second.myFunc(); // Should not execute
third.myFunc(); // Should not execute
Options:
member variable: If I use a member variable, then other functions within MyObj can access it and change it.
global static variable: Can't work because first,second and third will all be checking the same variable.
local static: Same problem as #2.
The only solution I have found, is to have MyObj inherit from another class
MyOtherObj{
private:
bool _isInit = false;
public:
bool isInit(){
bool ret = true;
if (!_isInit){
ret = false;
_isInit = true;
}
return ret;
}
};
class MyObj : public MyOtherObj {
public:
void MyFunc(){
if (!isInit()){
//Do stuff...
}
}
};
Any better suggestion ?
EDIT: I don't care about thread safety!
EDIT: I do not want to execute the method in the constructor, simply because the method may need to be executed much later in the lifetime of the object....
Use std::once_flag. It is not resettable from other methods (then again, if you cannot trust other methods of the same class, your development process is highly questionable), easy to use, and it is even thread-safe if you ever do care about that. It can be a bit less efficient in a single-threaded program.
#include <mutex>
class MyObj {
public:
void MyFunc() {
std::call_once(initFlag, [=] {
//Do stuff...
});
}
private:
std::once_flag initFlag;
};
I don't see what is wrong with Option 1. If a class has so many responsibilities that another function may accidentally mess with the is_init member variable then the class should probably be made smaller.
However, if you want to encapsulate into another class that is less error prone, rather than using inheritance, I suggest you use composition:
class FirstTime {
bool first_time = true;
public:
bool operator()(){
if (!first_time)
return false;
first_time = false;
return true;
}
};
class MyObj {
FirstTime first_time;
public:
void myFunc(){
if (first_time()){
std::cout << "First time!\n";
}
}
};
Live demo.
As with Option 1, you should think about what copy/move behavior do you want. e.g Should a copy of an initialized MyObj be considered initialized?
I see three reasonable options:
Just use your option #1, a bool member variable.
Create a little class for an init flag, that can be set, but not be unset.
Use the public non-virtual interface (NVI) idiom, if you really want to be sure, that no-one messes with your flag.
A bool member variable
This would be my first choice. Make it private, of course. If your class has so many other data fields, that adding this new member appears painful, then this could be a sign of bad design of the entire class in the first place.
Often init() methods can be avoided completely by splitting up a class into two: A class A that contains the constructed data before the call to init() and a class B that is initialized upon construction. That way you can see if an object is initialized only by its type.
An init flag that can be set, but not reset
This class could look somewhat like this:
class InitFlag
{
public:
void set()
{
isSet_ = true;
}
operator bool() const
{
return isSet_;
}
private:
bool isSet_ = false;
};
This way, member functions cannot mess up your flag as easily. As an author of a class, you should be able to trust your member functions enough, that they don't set this flag, unless they are called init().
The non-virtual interface idiom
You create a base class with an init() function that is public and non-virtual. This function checks, if init() has been called before, calls a private purely virtual doInit() function which is supposed to do the actual initialization and sets the init flag after that. It looks like this:
class InitializeBase
{
public:
virtual ~InitializeBase() = default;
bool isInit() const
{
return isInit_;
}
void init()
{
assert( !isInit() );
doInit();
isInit_ = true;
}
private:
virtual void doInit() = 0;
bool isInit_ = false;
};
This has several security advantages:
Derived classes cannot modify isInit_.
Derived classes cannot call doInit(), as long as they don't make it public or protected (which would be very nasty). However, they can and must implement this function.
Hence doInit() function is statically guaranteed not to be called more than once, unless an assert() will trigger.
If you don't want the init() function to be public, then you can derive with the protected or the private attribute from InitializeBase.
The obvious drawback is that the design is more complicated and you get an additional virtual function call. For this reason the NVI idiom has become somewhat controversial.
Here's a variant that wraps a function in a class.
Once the function is called, it's replaced with one that does nothing.
const std::function<void()> nop = [](){};
class Once
{
public:
Once(std::function<void()> f) : m_function(f) {}
void operator()()
{
m_function();
m_function = nop;
}
private:
std::function<void()> m_function;
};
class Foo
{
public:
Foo(int x)
: m_function([this](){m_x += 1;}),
m_x(x) {}
int get() const { return m_x; }
void dostuff() { m_function(); }
private:
int m_x;
Once m_function;
};
int main()
{
Foo f(0);
cout << f.get() << endl; // 0
f.dostuff();
cout << f.get() << endl; // 1
f.dostuff();
cout << f.get() << endl; // 1
}
molbdnilo's answer is pretty good and was along the same lines I was thinking. I've changed a few things which I personally think makes it more idiomatic.
#include <iostream>
#include <functional>
class Once
{
bool isDone = false;
public:
void exec(std::function<void()> function)
{
if (!isDone)
{
function();
isDone = true;
}
}
};
class MyObj {
Once once = Once();
public:
void myFunc()
{
once.exec( []{
std::cout << "Hello, world!";
// do some stuff
});
}
};
int main()
{
MyObj foo = MyObj();
foo.myFunc();
foo.myFunc();
foo.myFunc();
}
The solution at the top is very good, but this might be a better solution for an interesting special case.
I assume that the method shall only be executed once because it modifies the state of the class. For the special case that the method initializes some parts of the class, I think it is best to use an optional, either boost::optional or std::optional or std::experimental::optional, depending on what is available to you:
#include <boost/optional.hpp>
class X
{
public:
void init()
{
if( ! _x )
{
_x.reset( 5 );
}
}
private:
boost::optional<int> _x;
};

How to pass a linc to class function and call it?

So I have a class like
class mySafeData
{
public:
void Set( int i )
{
myMutex.lock();
myData = i;
myMutex.unlock();
}
void Get( int& i)
{
myMutex.lock();
i = myData;
myMutex.unlock();
}
private:
int myData;
boost::mutex myMutex;
};
its instance is running. Lets call instance A. I want to create a new class that would take as a start up argument some kind of link to Getter from A and would be capable to somehow save link to thet getter for calling it inside its private methods vhen needed. how to do such thing?
Sounds like you want something like this:
class myOtherData
{
public:
myOtherData(mySafeData& dataSource) :
myDataSource(&dataSource)
{}
private:
// note that if you take the advice in the comments,
// you don't need this wrapper function at all,
// it's simple just to call myDataSource.Get()
int GetData()
{
int result;
myDataSource.Get(result);
return result;
}
mySafeData* myDataSource;
};
mySafeData a;
myOtherData b(a);
// b uses a as its data source (make sure it lives as long!)
I'm not sure what you mean by linc/link. Are you asking for anything more than this pattern?
class Foo {
public:
Foo(mySafeData& d) : data(d) {}
int someFunction() {
int i;
data.get(i);
return i;
}
private:
mySafeData& data;
};
...
Foo f(a);
What's wrong with pointers? Smart, Shared, Scoped... I'll use standard pointers for now.
class B
{
public:
B(mySafeData* ptr) // constructor takes a memory pointer as parameter
:SafeData_ptr(ptr)
{
SafeData_ptr->foo(); // call public function from class A
}
~B() // destructor
{
}
private:
mySafeData* SafeData_ptr; // will hold the mem address of instance A when
// this class is initialized
};
Later on your code, when you have instance A ready, you would do something like this:
B b_demo(&A); // &A passes the memory address of the instantiated object
// and A::foo() will be automatically called when B is constructed.
This is probably not the smartest way to do it, but I think it illustrates the idea.

How to return same instance for every class initialization in C++?

I want to create a class that can only have one instance. If I try to make another instance of the class, it will return the first instance.
I think you are searching Singleton pattern in C++. Here is implementation and here linux tutorial for singleton pattern in C++
I think what you want is closer to MonoState, than Singleton.
MonoState works by having all objects share the same state through static member variables. Whilst the instances are different, the data returned by those is the same. Here is a simple implementation:
class MonoStateSession {
private:
static int _SessionId;
public:
void SetSessionId(int newSessionId) {
//Put threading checks/locks here
_SessionId = newSessionId;
}
int GetSessionId() {
return _SessionId;
}
}
//Usage
MonoStateSession session1 = new MonoStateSession();
session1.SetSessionId(123);
MonoStateSession session2 = new MonoStateSession();
assert(session2.GetSessionId() == 123);
No... but you can get close to that. For example you can create a class where every instance is just a clone of the same real object... for example:
struct TheRealObject
{
std::string s;
TheRealObject() { ... }
void foo(int x) { ... }
double bar(char y) { ... }
static TheRealObject& getInstance()
{
static TheRealObject trb;
return trb;
}
};
struct MyObject
{
std::string& s;
MyObject() : s(TheRealObject::getInstance().s) {}
void foo(int x) { TheRealObject::getInstance().foo(x); }
double bar(char y) { return TheRealObject::getInstance().bar(y); }
};
Note that every MyObject instance will still be a distinct object (with its own address for example) but they will just act as a trampoline to the only instance existing of TheRealObject both for method and data member access.
Why do you want to do something this strange? May be you're just looking for a singleton instead (like the TheRealObject in the above)?

Select subclass from base class...possible?

I am learning C++ and I am stuck with a problem. I need a way to use a specific subclass within base class. Does it make sense or I am using a wrong approach? SelectBrand should select the subclass, how can I do it?
Here below my simplified classes:
-----
class Protocol {
public:
Protocol() {};
~Protocol() {};
int openPort();
int readPort(char *buffer);
.....
private:
Protocol (const Protocol&);
};
int Protocol::openPort() {......};
int Protocol::readPort() {.........};
/***********************************************************************************/
class Device{
public:
Device(Protocol& port):_protocol(port){}
~Device();
virtual int getEvent(char *buffer) { return -1; }
int Device::selectBrand();
..............
protected:
Protocol& _protocol;
private:
int brand;
Device(const Device&orig);
};
Device::~Device() {}
int Device::selectBrand() {
......
switch (X)
case 1:
"use subclass Brand_B"
case 2:
"use subclass Brand_B"
.......
}
/***********************************************************************************/
class Brand_A:public Device {
public:
Brand_A(Protocol& port);
~Brand_A();
int getEvent(void *rawData);
private:
Brand_A(const Brand_A&);
};
Brand_A::Brand_A(Protocol& port):Device(port) {}
Brand_A::~Brand_A() {}
int Brand_A::getEvent(void *rawData) {
.... readPort(......);
}
/***********************************************************************************/
class Brand_B:public Device {
public:
Brand_B(Protocol& port);
~Brand_B();
int getEvent(void *rawData);
private:
Brand_B(const Brand_B&);
};
Brand_B::Brand_B(Protocol& port):Device(port) {}
Brand_B::~Brand_B() {}
int Brand_B::getEvent(void *rawData) {
.... readPort(......);
}
/* main **********************************************************/
int main(int argc, char **argv) {
Device *mydev;
char *buffer;
..............
mydev->selectBrand();
..........
mydev->getEvent(buffer);
...........
}
This is not a good idea.
Generally the answer is dynamic_cast, but invoking specific behavior of descendants from a base class is usually a bad design sign.
You can try inverting the class hierarchy and using templates.
I figured I should flesh out the comment I made above. First of all, you can check out the Wikipedia page for more information on the abstract factory pattern. Basically it allows you to access different implementations of an interface, with the implementation used determined at runtime. However, you still don't know which implementation you're getting as that is decided in the factory method that returns the implementation of the interface. As a result, you can only ever use the members in the interface and not a specific implementation. An example that uses your classes above would be something like:
class Device
{
virtual int getEvent(void *rawData) = 0;
}
class BrandA : public Device
{
// define constructors/destructors etc.
int getEvent(void *rawData)
{
// BrandA's implementation for getEvent
}
}
class BrandB : public Device
{
// define constructors/destructors etc.
int getEvent(void *rawData)
{
// BrandB's implementation for getEvent
}
}
class DeviceFactory
{
static Device *CreateDevice(/*any parameters for determining the device?*/)
{
// You probably don't want to randomly determine which implementation you use...
if ((rand() % 2) == 0)
{
return new BrandA();
}
else
{
return new BrandB();
}
}
}
int main()
{
// CreateDevice will decide which type of device we use, however we can only
// explicitly reference the members of the base class (Device).
Device *myDevice = DeviceFactory::CreateDevice();
myDevice->getEvent();
return 0;
}
It looks like you might be trying to implement something like polymorphism when C++ will do that for you. If you define virtual methods in your base class and override them in your sub classes, calls to those methods on a pointer or reference to the base type should result in the sub class' implementation being called.
For example:
class BaseClass
{
virtual void DoSomething()
{
printf("base");
}
};
class SubClass : public BaseClass
{
void DoSomething()
{
printf("sub");
}
};
int main()
{
BaseClass *myBase = new SubClass();
myBase->DoSomething(); // should print "sub" to stdout
return 0;
}
You have to know what derived type (type of subclass) you want to use when you create it so that the instance has the added functionality of the derived type. If you don't, all you get is the functionality of the base class, and you cannot treat it as anything but the base class (or anything further up the inheritance hierarchy if your base class inherits from something).
You may even want to use a member to differentiate between different instances if they're not actually doing anything different. It's hard to tell from the code example exactly what you want to do. Maybe a more specific example of what you're trying to achieve rather than how you're trying to achieve it would help.
please, let me reformulate the problem. I have 1 baseClass and some subclasses; Brand_A....Brand_N
Now, in the main() I don't know in advance which subclass I will use; this selection is demanded to a function in the baseClass which I called selectBrand. What I need is a mechanism to select and use the right subclass based on internal conditions. I want to masquerade to the main() the selected subclass. How to get this?
I implemented and tested this code; it works fine. Is it good design or can be done better?
class BehaviorBase
{
public:
virtual ~BehaviorBase() {}
virtual void DoSomethingOn(Object* obj) {}
};
class Object
{
public:
BehaviorBase* behavior;
void DoSomething();
void ChangeBehavior(int param);
~Object();
}
class BehaviorA: public BehaviorBase
{
void DoSomethingOn(Object* obj)
{
printf("Behavior A\n");
}
};
class BehaviorB: public BehaviorBase
{
string other_data;
void DoSomethingOn(Object* obj)
{
printf("Behavior B\n");
}
};
void Object::DoSomething()
{
behavior->DoSomethingOn(this);
}
Object::~Object()
{
delete behavior;
}
void Object::ChangeBehavior(int param)
{
delete behavior;
switch(param)
{
case 1: behavior = new BehaviorA; break;
case 2: behavior = new BehaviorB; break;
}
}
int main(int argc, char **argv) {
int param=1;
Object *obj;
obj= new Object;
obj->ChangeBehavior(param);
obj->DoSomething();
delete obj;
return(0);
}