簡體   English   中英

可以繼承一個類,但不能繼承該類嗎? (qt)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM