[英]c++ Is it possible to inherit a class, but not what that class inherits? (qt)
我現在有四節課。 客戶端,ChatWindow,FunctionCall和MainWindow。 我最終想要做的是沒有FunctionCall類,並且在ChatWindow和MainWindow中沒有Client的虛擬繼承,但是QT或更具體地說QObject不允許這樣做。
我認為虛擬類會很好的原因是不要創建一個類的兩個不同實例,而是讓ChatWindow和MainWindow共享變量。
我制作了一個繼承Client的FunctionCall類,並使用FunctionCall在ChatWindow和MainWindow之間創建了虛擬繼承。
聊天窗口
#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
FunctionCall.h
#ifndef FUNCTIONCALL_H
#define FUNCTIONCALL_H
#include "client.h"
class FunctionCall : public Client
{
public:
FunctionCall();
};
#endif // FUNCTIONCALL_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類,並創建了該類的實例。
不可以,因為那樣會違反類型等效性(Liskov替換原理)。 基本上,這意味着因為您從Client
繼承,所以每個FunctionCall
對象也將是一個Client
對象,並且由於每個Client
對象必須是一個QDialog
對象,因此, FunctionCall
對象也必須是一個QDialog
對象。
同樣,您在這里似乎是受害者,因為您使用了多重繼承,並且相同(非虛擬)的基礎在繼承樹中出現了兩次。 您可能應該三思而后行:這真的是正確的設計嗎? 這真的是您想要的嗎? 請注意,繼承樹中QWidget
的不同位置是不同的(子)對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.