This is the first time that I am splitting my library functionality into multiple classes. I am not exactly sure how to instantiate my objects per the classes. Am I required to instantiate the class objects in order to access those class methods and variables even though the classes are in the same .h file? I am receiving the error ‘incomplete type is not allowed’ for line 30.
My code:
/*
File: sensor.h
Header file for phSensor Library.
*/
#ifndef SENSOR_H
#define SENSOR_H
#include "mbed.h"
#include "cfExtensions.h"
#include "msExtensions.h"
#include <string>
class phSensor;
class ecSensor;
class tempSensor;
class sensor
{
public:
sensor(); //Default sensor constructor
sensor(cfExtensions &cfExt, msExtensions &msExt);
private:
cfExtensions &_cfExt;
msExtensions &_msExt;
phSensor ph; // Line 30, gets error "incomplete type is not allowed"
ecSensor ec;
tempSensor temp;
string _phCurrentPhValue;
string _phMaxValue;
string _phMinValue;
};
class phSensor
: public sensor
{
public:
phSensor();
void outputPhMaxValue();
private:
float _getCurrentPhValue();
float _getPhMaxValue();
float _getPhMinValue();
void _setPhMaxValue();
void _setPhMinValue();
void _calibratePhSensor();
Ticker getPhMax;
Ticker getPhMin;
};
class ecSensor
: public sensor
{
public:
ecSensor();
};
class tempSensor
: public sensor
{
public:
tempSensor();
};
#endif
Others have already commented about the problem with the declaration
phSensor ph;.I’m going to comment about your design.
About your
class sensorFirst off, why are you doing this?
One of the first things you learn in object oriented is about inheritance, for example a
Vehicleclass, withCar,Truck, andBicycleall being subclasses of that base vehicle class. Very nice, very simple, but often wrong. Eventually you need to unlearn that naive view of object oriented programming.Case in point: Just because pH sensors, electrical conductivity sensors, and temperature sensors are all sensors of some type does not necessarily mean that it is a good idea to make a
Sensorbase class. What are the common elements shared by all sensors? If there are none, perhaps it’s not such a good idea to have thatsensorbase class.Do one thing and do it well
Your
sensorclass is doing two things. It is serving as a base class for those other sensor classes and it is serving as a collection of three kinds of sensors. These are two very different things, so these different behaviors should be in two very different classes. Your immediate problems would go away if you split that class into two classes,sensorto act as the base class (if needed; see above) and amultisensorthat contains a pH sensor, an electrical conductivity sensor, and a temperature sensor. There’s no need to make thismultisensorclass inherit fromsensor, or even fromphsensoretc. This new class would instead contain multiple sensors. Composition is oftentimes a much better route than inheritance.About the class
sensorconstructorsYou have two data members that are references. References can only be set by a constructor, and only in the initializer list. I can see what the non-default constructor does. What does your default constructor do? Your derived classes only have default constructors, which suggests that they are calling the
sensorclass’s default constructor. Does this make sense? It might be better to get rid of those default constructors. The standard way to do this in C++03 is to declare the default constructor private but never provide an implementation. There’s a better option in C++11, which is to declare the constructor as deleted.