C++可以继承类,而不继承该类?(qt)

C++可以继承类,而不继承该类?(qt),c++,qt,inheritance,C++,Qt,Inheritance,我现在有四节课。客户端、聊天窗口、函数调用和主窗口。我最后想做的是不使用FunctionCall类,在ChatWindow和MainWindow中对客户端进行虚拟继承,但QT,或者更具体地说QObject不允许这样做 我认为虚拟类最好的原因是不要创建一个类的两个不同实例,而是让ChatWindow和MainWindow共享变量 我创建了一个继承客户端的FunctionCall类,并使用FunctionCall在ChatWindow和MainWindow之间创建了虚拟继承 聊天窗口 #ifndef

我现在有四节课。客户端、聊天窗口、函数调用和主窗口。我最后想做的是不使用FunctionCall类,在ChatWindow和MainWindow中对客户端进行虚拟继承,但QT,或者更具体地说QObject不允许这样做

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

我创建了一个继承客户端的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
客户: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
解决了我的问题:
我基本上创建了一个客户机类的单例,并创建了该类的实例。

否,因为这将违反类型等价性Liskov替换原则。基本上这意味着,由于您从客户端继承,每个FunctionCall对象也将是客户端对象,并且由于每个客户端对象都必须是QDialog对象,因此FunctionCall对象必须是QDialog对象


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

我想说,继承不是这里的解决方案,而是像中一样的组合,例如,使您的ChatWindow类有一个QMainWindow和一个客户端成员左右,没有更多的上下文很难判断。我将遇到与现在相同的错误。对'show'的模糊访问可能是基'QWidget'中的'show',也可能是基'QWidget'中的'show',如果我从客户端继承,在MainWindow和ChatWindow中,它将创建两个我不想要的客户端实例。我将有与现在相同的错误。不,你不会,ChatWindow和MainWindow都会从任何东西派生出来。->在任何语言中,说“Mainwindow是FunctionCall”或“FunctionCall是客户端”都是有意义的,这表明您的设计有问题什么是错误?这似乎编译得很完美。我基本上创建了一个客户机类的单例,并创建了该类的实例。-注意矛盾。不,这不是我想要的。在我更改代码之前,我所拥有的是客户端是基类,而MainWindow和ChatWindow只继承了基类。但这不起作用,因为它创建了一个类的两个实例,每次我调用一个新函数时,变量都会重置。
    #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
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'