这是我第一次将库功能拆分为多个类。我不确定如何根据类实例化我的对象。我是否需要实例化类对象才能访问那些类方法和变量,即使这些类在同一个.h文件中?我收到第30行的错误“不允许的不完整”。
我的代码:
/*
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
答案 0 :(得分:2)
在您的情况下,您只能声明指针或对不完整类型的引用
phSensor ph;
ecSensor ec;
tempSensor temp;
所有这些都会产生错误,如果不知道所有成员的布局,就无法定义sensor
的布局。
此外,对象不可能包含其自己类的子对象,但这就是您要尝试做的事情 - phSensor
和ecSensor
都继承sensor
并且sensor
的成员。最有可能你需要这些作为指针。
phSensor *ph;
ecSensor *ec;
tempSensor *temp;
答案 1 :(得分:2)
其他人已经对声明phSensor ph;
的问题发表了评论。
我要评论你的设计。
关于您的class sensor
首先,你为什么要这样做?
您在面向对象中学到的第一件事就是继承,例如Vehicle
类,Car
,Truck
和Bicycle
都是子类基础车辆类。非常好,非常简单,但经常是错误的。最终你需要忘掉面向对象编程的天真观点。
例证:仅仅因为pH传感器,电导率传感器和温度传感器都是某种类型的传感器并不一定意味着建立Sensor
基类是个好主意。所有传感器共有哪些共同元素?如果没有,那么拥有sensor
基类也许不是一个好主意。
做一件事,做得好
你的sensor
课正在做两件事。它作为其他传感器类和的基类,它作为三种传感器的集合。这是两个非常不同的东西,所以这些不同的行为应该在两个非常不同的类中。如果将该类拆分为两个类,sensor
作为基类(如果需要,请参见上文)和multisensor
包含pH传感器,电导率传感器,您的直接问题就会消失和温度传感器。没有必要让这个multisensor
类继承自sensor
,甚至来自phsensor
等。这个新类将包含多个传感器。组合通常是比继承更好的途径。
关于班级sensor
施工人员
您有两个引用的数据成员。引用只能由构造函数设置,并且只能在初始化列表中设置。我可以看到非默认构造函数的作用。你的默认构造函数有什么作用?派生类只有默认构造函数,这表明它们正在调用sensor
类的默认构造函数。这有意义吗?摆脱那些默认构造函数可能会更好。在C ++ 03中执行此操作的标准方法是将默认构造函数声明为private,但从不提供实现。在C ++ 11中有一个更好的选择,即将构造函数声明为已删除。
答案 2 :(得分:1)
您声明了phSensor类,因此类型名称已知。但是,此时编译器对该类的成员或方法一无所知,因此无法知道该类型的大小。只要该类仅被声明且未定义,您只能使用指针或引用。
另外:如果你仔细观察你的班级布局,这是行不通的。 让我们说你实例化phSensor。 phSensor扩展了传感器,因此传感器的所有成员也被初始化。其中一个成员再次是phSensor,它来自传感器,它拥有另一个phSensor继承传感器等等。你看,这个实例化永远不会结束并耗尽所有内存。
答案 3 :(得分:1)
您不应该在同一个文件中声明这些类。如果你这样做,模块化代码的想法就没有意义。