c ++是否可以继承一个类,但不能继承该类的继承? (QT)

时间:2015-11-07 10:16:25

标签: c++ qt inheritance

目前我有四节课。客户端,ChatWindow,FunctionCall和MainWindow。我最终想要做的是没有FunctionCall类,并且在ChatWindow和MainWindow中有一个Client的虚拟继承,但是QT,或者更具体地说QObject不允许这样做。

我认为虚拟类很好的原因是不创建类的两个不同实例,而是让ChatWindow和MainWindow共享变量。

我已经创建了一个继承Client的FunctionCall类,并且我已经使用FunctionCall在ChatWindow和MainWindow之间创建了虚拟继承

ChatWindow.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

FunctionCall.h

    #ifndef FUNCTIONCALL_H
#define FUNCTIONCALL_H

#include "client.h"

class FunctionCall : public Client
{
public:
    FunctionCall();

};

#endif // FUNCTIONCALL_H

Client.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类的单例,并创建了它的实例。

1 个答案:

答案 0 :(得分:0)

不,因为这会违反类型等效(Liskov Substitution Principle)。基本上它意味着,由于您从Client继承,每个FunctionCall对象也将是一个Client对象,因为每个Client对象都必须是QDialog个对象遵循FunctionCall对象必须是QDialog对象。

此外,您似乎成为受害者的是您使用多重继承,并且在继承树中出现两次相同(非虚拟)基础。你可能应该三思而后行三次:这真的是正确的设计吗?这真的是你想要的吗?请注意,继承树中QWidget的不同位置是不同的(子)对象。