Passing already initiated class to another class' constructor

Hello,

I am creating a class to encapsulate some code that is used by other parts of my program. For simplicity's sake, let's say that my sketch has two files--a sketch.ino file and a myclass.h file.

In the sketch.ino file I include a library called MCP23017.h, and I create a variable called gpio of that class:

MCP23017 gpio(0x20, 5);

In the sketch.ino file I can use the gpio variable to control the MCP23017 chip without issue.

In the myclass.h file I want to also control the MCP23017 chip, so I want to pass the gpio variable to the constructor of MyClass. The class would look something like this (I'm excluding the #ifndef stuff).

class MyClass{

private:
  MCP23017 _mygpio;

public:
  MyClass (MCP23017* gpio){
    _mygpio=gpio;
  }
}

I then try to create an instance of MyClass using

MyClass myclass(&gpio);

This gives me errors, "error: no matching function for call to 'MCP23017::MCP23017()'".

The whole point of passing the gpio variable from sketch.ino to myclass.h is to avoid creating a second instance of the MCP23017 class. I need that class in both files, so I can't just create it in myclass.h.

I've seen similar posts, but the all appear to be passing the object that isn't already initialized. Is this the same thing?

I know that I can pass gpio from sketch.ino to a function in a different file in the sketch when it's not a class using doSomething(&gpio), but when I do that, i don't assign it to a variable inside of that function and try to use the variable, I just use it as gpio->.

I guess my question is, "Is this possible, and if so, just how far off base am I from the correct format?"

Thanks in advance!

Yes, it's an example of a concept known as Dependency Injection.

The reason for the error is that you have now created a parameterized constructor to take the gpio object, but there's no longer a default (non-parameterized) constructor.

Add this

private:
MyClass() {}

That should take care of the error.

Thanks for responding. I tried this and got the same error. But I figured out what was causing the error. It's the way I declared the private variable. I declared it this way:

private:
  MCP23017 gpio;

The problem is that using that format, I'm declaring it as an instance of the class instead of as a pointer. When I changed it to:

private:
  MCP23017* gpio;

It worked. Here's my complete code of a stupid example:

This is the main sketch

#include <MCP23017.h>
#include "myclass.h"
#include <Wire.h>
//#include "noclass.h"

MCP23017 gpio(0x20, 5);

MyClass myclass(&gpio);

void setup() {
  Serial.begin(115200);
  Wire.begin();
  if (!gpio.Init()){
    Serial.println("Unable to connect");
  }
  gpio.setPortMode(0b11111100, A);
  myclass.setPin(3, A, HIGH);
}

void loop() {
}

And this is the class

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass {

private:
  MCP23017* _myGPIO;      // has to include the *

public:
  MyClass() {}

  MyClass(MCP23017* gpio) {
    this->_myGPIO = gpio;           // no need for &, also use this->
  }

  void setPin(uint8_t pin, mcp_port port, uint8_t state) {
    this->_myGPIO->setPin(pin, port, state);
       // use this->_myGPIO-> to call methods  or access properties in _myGPIO
  }
};
#endif

I'm sure some of the vocabulary I'm using is not correct, and I apologize for that. I'm not a C++ coder by trade.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.