2015-11-07 4 views
0

У меня есть четыре класса на данный момент. Client, ChatWindow, FunctionCall и MainWindow. То, что я умышленно хотел бы сделать, - это не иметь класс FunctionCall и иметь виртуальное наследование клиента в ChatWindow и MainWindow, но QT или, более конкретно, QObject этого не допускает.C++ Возможно ли наследовать класс, но не то, что наследует этот класс? (qt)

Причина, по которой я думал, что виртуальный класс будет хорош, состоит в том, чтобы не создавать два разных экземпляра класса, а иметь ChatWindow и MainWindow совместно использовать переменные.

Я сделал класс, который наследуется FunctionCall клиента, и я создал виртуальное наследование между ChatWindow и MainWindow с FunctionCall

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 

Проблема я получаю сообщение об ошибке, вероятно, потому, что класс наследует клиент QDialog.

Мне было интересно, можно ли только наследовать от Клиента, а не то, что клиент также наследует, в основном я хочу использовать функции в классе 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' 

решаемых мой вопрос: Я в основном сделал одноплодный класс клиента, и создал экземпляры этого.

+9

Я бы сказал, что наследование не является решением здесь, а скорее составом (как и в, например, у вашего класса ChatWindow есть QMainWindow и член клиента или так, трудно сказать, без дополнительного контекста). – stijn

+0

У меня такая же ошибка, как у меня сейчас. «двусмысленный доступ к« шоу »может быть« показом »в базе« QWidget »или может быть« показом »в базе« QWidget », если я унаследовал от клиента, как в MainWindow, так и в ChatWindow, он создаст два экземпляра Client которого я не хочу. – Emsal

+0

* У меня такая же ошибка, как у меня сейчас. * Нет, вы бы этого не сделали, ChatWindow и MainWindow получались бы от всего. https: //en.wikipedia.org/wiki/Is-a -> говорит: «Mainwindow - это FunctionCall», а «FunctionCall - это клиент» имеет смысл на любом языке, что указывает на то, что в вашем дизайне что-то не так. – stijn

ответ

0

Нет, поскольку это нарушит эквивалентность типа (принцип замены Лискова). В основном это означает, что, поскольку вы наследуете от Client, каждый объект FunctionCall также будет объектом Client, и поскольку каждый объект Client должен быть объектом QDialog, это значит, что объект FunctionCall должен быть объектом QDialog.

Кроме того, вы являетесь жертвой здесь, так это то, что вы используете множественное наследование, и одна и та же (не виртуальная) база появляется дважды в дереве наследования. Вы, вероятно, должны подумать дважды или трижды об этом: действительно ли это правильный дизайн? это действительно то, что вы хотите? Обратите внимание, что различные события QWidget в дереве наследования являются разными (вспомогательными) объектами.

+0

Нет, это действительно не то, что я хочу. То, что у меня было до того, как я изменил код, было то, что Клиент был базовым классом, а MainWindow и ChatWindow унаследовали только от этого. Но это не работает, потому что он создает два экземпляра класса и каждый раз, когда я вызываю функцию, новая функция сбрасывает переменные. – Emsal

Смежные вопросы