【发布时间】:2015-11-07 10:16:24
【问题描述】:
我现在有四节课。客户端、ChatWindow、FunctionCall 和 MainWindow。我最终想要做的是没有 FunctionCall 类并且在 ChatWindow 和 MainWindow 中有 Client 的虚拟继承,但是 QT,或者更具体地说 QObject 不允许这样做。
我认为虚拟类很好的原因是不要创建一个类的两个不同实例,而是让 ChatWindow 和 MainWindow 共享变量。
我已经创建了一个继承 Client 的 FunctionCall 类,并且我已经使用 FunctionCall 在 ChatWindow 和 MainWindow 之间创建了虚拟继承
聊天窗口.h
#ifndef CHATWINDOW_H
#define CHATWINDOW_H
#include <QWidget>
#include "functioncall.h"
namespace Ui {
class ChatWindow;
}
class ChatWindow : public QMainWindow, public virtual FunctionCall
{
Q_OBJECT
public:
explicit ChatWindow(QWidget *parent = 0);
~ChatWindow();
private slots:
void on_sendButton_clicked();
private:
Ui::ChatWindow *ui;
};
#endif // CHATWINDOW_H
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "functioncall.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow, public virtual FunctionCall
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_connectButton_clicked();
private:
Ui::MainWindow *ui;
protected:
void something();
};
#endif // MAINWINDOW_H
函数调用.h
#ifndef FUNCTIONCALL_H
#define FUNCTIONCALL_H
#include "client.h"
class FunctionCall : public Client
{
public:
FunctionCall();
};
#endif // FUNCTIONCALL_H
客户端.h
#ifndef CLIENT_H
#define CLIENT_H
#include <QApplication>
#include <QWidget>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QTcpSocket>
#include <QString>
#include <QTcpServer>
#include <QStringList>
#include <QNetworkSession>
#include <QDataStream>
#include <QGridLayout>
#include <QMainWindow>
class Client : public QDialog
{
Q_OBJECT
public:
Client(QWidget *parent = 0);
public slots:
void read();
void displayError(QAbstractSocket::SocketError socketError);
void sessionOpened();
void connectedSocket();
void disconnectedSocket();
void pushToSocket(
quint8 registerForm,
QString registerUsername,
QString registerPassword,
QString username,
QString text
);
QString readFromSocket();
void saveToFile(std::string fileName, QString text);
public:
QTcpSocket *tcpSocket;
quint16 blockSize;
QNetworkSession *networkSession;
QTcpServer *tcpServer;
struct HeaderFile {
quint8 registerForm = 2;
QString registerUsername;
QString registerPassword;
QString username;
QString text;
};
public:
QStringList *hostCombo;
void send(QString username, QString text);
void loginRegisterConnect(QString host, int port, QString username, QString password);
friend QDataStream & operator<<(QDataStream& str, const HeaderFile & data) {
str << data.registerForm << data.registerUsername << data.registerPassword << data.username << data.text;
return str;
}
friend QDataStream & operator>>(QDataStream& str, HeaderFile & data) {
str >> data.registerForm >> data.registerUsername >> data.registerPassword >> data.username >> data.text;
return str;
}
};
#endif // CLIENT_H
问题是我遇到了一个错误,可能是因为 Client 类继承了 QDialog。
我想知道是否可以仅从 Client 继承,而不是 Client 也继承,基本上我想使用 Client 类中的功能。但它没有从 QDialog 继承。
这里没有编译是错误的:
C:\\main.cpp:9: error: C2385: ambiguous access of 'show'
could be the 'show' in base 'QWidget'
or could be the 'show' in base 'QWidget'
解决了我的问题: 我基本上制作了 Client 类的单例,并创建了它的实例。
【问题讨论】:
-
我想说继承不是这里的解决方案,而是组合(例如,让你的 ChatWindow 类有一个 QMainWindow 和一个 Client 成员左右,如果没有更多上下文很难说)。
-
我会遇到和现在一样的错误。 “'show'的模糊访问可能是基础'QWidget'中的'show'或者可能是基础'QWidget'中的'show'”如果我从客户端继承,在MainWindow和ChatWindow中,它将创建两个客户端实例这是我不想要的。
-
我会遇到和现在一样的错误。 不,你不会,ChatWindow 和 MainWindow 会派生自任何东西。 en.wikipedia.org/wiki/Is-a -> 说“Mainwindow 是 FunctionCall”或“FunctionCall 是 Client”在任何语言中都是有意义的,这表明您的设计有问题
-
什么是“错误”?这似乎编译得很完美。
-
“我基本上做了一个客户端类的单例,并创建了它的实例。” - 注意矛盾。
标签: c++ qt inheritance