Search code examples
c++classobjectdriverhardware

How to access same resource from multiple objects?


I am relatively new to C++ OOP, so please be patient with me.

I am using a 3rd party drivers for CAN bus protocol that's implemented for dedicated hardware (PCIE module). It comes with a class that allows you to instantiate can_read and can_write objects.

This library is used in my own program where I have a class and 7 instances of the aforementioned class that need access the can_write object which is defined in a global scope in the main file.

The issue I am having is the can_write object. As its a driver level library it's accessing the same memory address from the can_write object. If I have a member function that takes can_writer by value, the program crashes whenever it's accessed with "double free or corruption" error.

I am now passing the can_writer object by reference ("CanClass &a" for the argument) and it seems to work, however I am not sure if that's a good practice or a conventional way of doing it. Is that the right way of doing it? If not, what is the right way? Any references or even a brief explanation would be really helpful!

EDIT: I must avoid creating copies of can_writer as it will read to memory corruption, hence all 7 instances of my Class Foo need to access the exact same instance of can_write.


Solution

  • You could use a variation of a singleton pattern (https://en.wikipedia.org/wiki/Singleton_pattern) on your class.

    For example, you could have a get_can_write() method that check if a can_write object is instantiated, if so a reference to this object is returned, otherwise it creates an object can_write, keeps a reference to it and returns it.

    Your class that provides can_write and can_read would look like this :

    class Bar {
    private:
        static can_write* cw;
        static can_read* cr;
    
    public:
        static can_write* get_can_write(){
            if(cw == null)
                cw = new can_write;
            return cw;
        }
    
        static can_read* get_can_read(){
            if(cr == null)
                cr = new can_read;
            return cr;
        }
    }
    

    And the classes that use can_write and can_read would look like :

    class Foo{
    public:
        void doSomeRead(){
            string s = Bar::get_can_read()->doSomething();
        }
    
        void doSomeWrite(){
            Bar::get_can_write()->doSomething("test");
        }
    }