C++ 通过重写非虚方法对QIODevice进行子类化
我想从QIODevice中创建子类,因为我正在创建我的自定义设备(自定义串行端口对象) 我看到:C++ 通过重写非虚方法对QIODevice进行子类化,c++,qt,inheritance,virtual-functions,C++,Qt,Inheritance,Virtual Functions,我想从QIODevice中创建子类,因为我正在创建我的自定义设备(自定义串行端口对象) 我看到: writeData(const char *, qint64 ) : qint64 readData(char *, qint64 ) : qint64 在QIODevice接口中声明为虚拟,但不是方法: read(char *, qint64 ) : qint64 write(const char *, qint64 ) : qint64 然后在我的项目中,我有一个串行端口管理器类,如下所示:
writeData(const char *, qint64 ) : qint64
readData(char *, qint64 ) : qint64
在QIODevice接口中声明为虚拟,但不是方法:
read(char *, qint64 ) : qint64
write(const char *, qint64 ) : qint64
然后在我的项目中,我有一个串行端口管理器类,如下所示:
class SerialPortManager{
public:
SerialPortManager(int type){
if (type == 1)
genericSerialPort = new QSerialPort(); //QT framework
else if (type == 2)
genericSerialPort = new MySerialPort(); //my custom object, derived from QIODevice
}
qint64 write(char * data, qint64 size)
{
genericSerialPort->write(data, size);
}
private:
QIODevice* genericSerialPort = 0;
};
class MySerialPort : public QIODevice{
Q_OBJECT
public:
explicit MySerialPort(QObject *parent = Q_NULLPTR);
virtual ~MySerialPort();
qint64 readData(char *data, qint64 maxSize);
qint64 writeData(const char *data, qint64 maxSize);
qint64 write(char * data, qint64 size);
...
};
我的自定义串行端口(MySerialPort.h)定义如下:
class SerialPortManager{
public:
SerialPortManager(int type){
if (type == 1)
genericSerialPort = new QSerialPort(); //QT framework
else if (type == 2)
genericSerialPort = new MySerialPort(); //my custom object, derived from QIODevice
}
qint64 write(char * data, qint64 size)
{
genericSerialPort->write(data, size);
}
private:
QIODevice* genericSerialPort = 0;
};
class MySerialPort : public QIODevice{
Q_OBJECT
public:
explicit MySerialPort(QObject *parent = Q_NULLPTR);
virtual ~MySerialPort();
qint64 readData(char *data, qint64 maxSize);
qint64 writeData(const char *data, qint64 maxSize);
qint64 write(char * data, qint64 size);
...
};
这里发生的事情是,如果我创建一个类型为1(QSerialPort
实例)的SerialPortManager
对象,并对其调用write
,则调用QSerialPort
上的write
函数。
相反,如果我创建了一个类型为2的SerialPortManager
对象(MySerialPort
实例),并在其上调用write
,则不会调用write
函数
那么,是否可以覆盖QIODevice
的非虚拟方法write
?
否则,如果
write
和read
不是虚拟的,如何创建自定义QIODevice
。如果写入和读取不是虚拟的,则不会覆盖它们
readData
和writeData
是纯虚拟的,受保护。所以我假设write
和read
将在内部调用这些函数
至于为什么它们不可重写,您必须询问Qt设计者。它们很可能修改一些内部状态等,这些状态是私有的,因此必须在这些调用中进行包装
通常,Qt类设计得非常好,因此我假设您首先不需要重写
write
和read
。如果您这样做,您的设计可能会有一些问题。这是由设计完成的。如果写入和读取不是虚拟的,则不会覆盖它们
readData
和writeData
是纯虚拟的,受保护。所以我假设write
和read
将在内部调用这些函数
至于为什么它们不可重写,您必须询问Qt设计者。它们很可能修改一些内部状态等,这些状态是私有的,因此必须在这些调用中进行包装
通常,Qt类设计得非常好,因此我假设您首先不需要重写
write
和read
。如果您这样做,您的设计可能会出现一些问题。您无法覆盖非虚拟方法,只能对它们进行阴影处理,这是没有帮助的。您必须重写write_数据,而不是write(您不能这样做)。@n.m.假设我重写just writeData方法。如果我在我的对象上调用write,会发生什么?如果基类在其write方法上调用我的writeData实现,是否调用了它?文档就是这样记录的。“如果基类在其写方法上调用我的writeData实现,是否调用了它?”是的,这就是writeData是虚拟的。如果没有Qt的调试构建,您将一事无成。一旦有了它,就可以使用它来跟踪调用'QIODevice::read'或'write'时发生的事情。那你就会明白了。真的。你不能覆盖非虚拟方法,你只能对它们进行阴影处理,这是没有用的。您必须重写write_数据,而不是write(您不能这样做)。@n.m.假设我重写just writeData方法。如果我在我的对象上调用write,会发生什么?如果基类在其write方法上调用我的writeData实现,是否调用了它?文档就是这样记录的。“如果基类在其写方法上调用我的writeData实现,是否调用了它?”是的,这就是writeData是虚拟的。如果没有Qt的调试构建,您将一事无成。一旦有了它,就可以使用它来跟踪调用'QIODevice::read'或'write'时发生的事情。那你就会明白了。真的。好的,但如果我在对象上调用read或write方法,则不会调用重写的writeData和readData。一般来说,如果我在类上调用read,则基类的read被调用,对吗?然后,在其实现上,假设它调用虚拟readData。它是基于还是派生的readData?您是否已打开设备并处于读/写模式?在实际进行写/读操作之前,您可能会遇到错误。检查write/read的返回值,并使用errorString()
检查错误您的类中不应该有read
函数。所以它只有基类函数QIODevice
本身没有readData
(它是纯虚拟的),因此将调用您的。但是根据基本的OO原则,派生的函数将被调用。如果你不确定什么时候用虚拟函数调用什么函数并覆盖它们,我想最好编写一些小程序(没有qt,只有一些类),然后自己尝试一下。这有助于理解其工作原理。好的,但如果我在对象上调用read或write方法,则不会调用重写的writeData和readData。一般来说,如果我在类上调用read,则基类的read被调用,对吗?然后,在其实现上,假设它调用虚拟readData。它是基于还是派生的readData?您是否已打开设备并处于读/写模式?在实际进行写/读操作之前,您可能会遇到错误。检查write/read的返回值,并使用errorString()
检查错误您的类中不应该有read
函数。所以它只有基类函数QIODevice
本身没有readData
(它是纯虚拟的),因此将调用您的。但是根据基本的OO原则,派生的函数将被调用。如果你不确定什么时候用虚拟函数调用什么函数并覆盖它们,我想最好编写一些小程序(没有qt,只有一些类),然后自己尝试一下。这有助于理解其工作原理。