0

I have four classes at the moment. Client, ChatWindow, FunctionCall and MainWindow. What I ultimatly would want to do is not have FunctionCall class and have a virtual inheritance of Client in ChatWindow and MainWindow, but QT, or more specifically QObject doesn't allow this.

The reason I thought a virtual class would be good is to not create two different instances of a class, but rather have ChatWindow and MainWindow share the variables.

I've made a FunctionCall class that inherits Client, and I've created virtual inheritance between ChatWindow and MainWindow with 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

Problem is I'm getting an error, probably because the Client class inherits QDialog.

I was wondering if it was possible only to inherit from Client, and not what Client also inherits, basically I want to use the functions in the Client class. But nothing it inherits from QDialog.

It doesn't compile here is the error:

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'

Solved my issue: I basically made a singleton of the Client class, and created instances of that.

Emsal
  • 107
  • 9
  • 9
    I'd say inheritance is not the solution here, but rather composition (as in, make e.g. your ChatWindow class have a QMainWindow and a Client member or so, hard to tell without more context). – stijn Nov 07 '15 at 10:19
  • I wold have the same error as I have now. "ambiguous access of 'show' could be the 'show' in base 'QWidget' or could be the 'show' in base 'QWidget'" if I inherited from Client, in both MainWindow and ChatWindow, it would create two instances of Client which I don't want. – Emsal Nov 07 '15 at 10:24
  • *I wold have the same error as I have now.* no you wouldn't, ChatWindow nor MainWindow would derive from anything. https://en.wikipedia.org/wiki/Is-a -> saying 'Mainwindow is a FunctionCall' nor 'FunctionCall is a Client' makes sense in any language, which is an indication something is wrong in your design – stijn Nov 07 '15 at 10:30
  • What's "an error"? This seems to compile perfectly. – Christian Hackl Nov 07 '15 at 10:30
  • Sorry I'm tired, I didn't understand what you mean by member? @stijn – Emsal Nov 07 '15 at 10:42
  • A class member. See http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance for instance – stijn Nov 07 '15 at 11:15
  • I don't understand how this will solve my problem, I changed my code looking at the example from your link so that it only creates instances of Client, but this creates two different instances, because I need the Client class in both MainWindow and ChatWindow. I can update my question with the code if you want to. – Emsal Nov 07 '15 at 11:39
  • I basically made a singleton of the Client class, and created instances of that. Wow ... You guys won't probably believe me, but 16h. – Emsal Nov 07 '15 at 12:38
  • 1
    *"I basically made a singleton of the Client class, and created instances of that."* - Note the contradiction. – Christian Hackl Nov 07 '15 at 14:53

1 Answers1

0

No, because that would violate the type equivalency (Liskov Substitution Principle). Basically it means that since you inherit from Client every FunctionCall object will also be a Client object and since every Client object has to be a QDialog object it follows that the FunctionCall object has to be a QDialog object.

Also what you've seem to be victim of here is that you use multiple inheritance and the same (non-virtual) base appears twice in the inheritance tree. You probably should think twice or thrice about this: is this really the right design? is this really what you want? Note that the different occations of QWidget in the inheritance tree are different (sub) objects.

skyking
  • 13,817
  • 1
  • 35
  • 57
  • No that's really not what I want. What I had before I changed the code was that the Client was the base class, and the MainWindow and ChatWindow only inherited from that. But that doesn't work because it creates two instances of a class and every time I call a function a new function the variables are reset. – Emsal Nov 07 '15 at 10:58