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

Posted

技术标签:

【中文标题】c ++是不是可以继承一个类,但不能继承该类的继承? (qt)【英文标题】:c++ Is it possible to inherit a class, but not what that class inherits? (qt)c ++是否可以继承一个类,但不能继承该类的继承? (qt) 【发布时间】:2015-11-07 10:16:24 【问题描述】:

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

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

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

聊天窗口.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

函数调用.h

    #ifndef FUNCTIONCALL_H
#define FUNCTIONCALL_H

#include "client.h"

class FunctionCall : public Client

public:
    FunctionCall();

;

#endif // FUNCTIONCALL_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

问题是我遇到了一个错误,可能是因为 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 类的单例,并创建了它的实例。

【问题讨论】:

我想说继承不是这里的解决方案,而是组合(例如,让你的 ChatWindow 类有一个 QMainWindow 和一个 Client 成员左右,如果没有更多上下文很难说)。 我会遇到和现在一样的错误。 “'show'的模糊访问可能是基础'QWidget'中的'show'或者可能是基础'QWidget'中的'show'”如果我从客户端继承,在MainWindow和ChatWindow中,它将创建两个客户端实例这是我不想要的。 我会遇到和现在一样的错误。 不,你不会,ChatWindow 和 MainWindow 会派生自任何东西。 en.wikipedia.org/wiki/Is-a -> 说“Mainwindow 是 FunctionCall”或“FunctionCall 是 Client”在任何语言中都是有意义的,这表明您的设计有问题 什么是“错误”?这似乎编译得很完美。 “我基本上做了一个客户端类的单例,并创建了它的实例。” - 注意矛盾。 【参考方案1】:

不,因为这会违反类型等效性(Liskov 替换原则)。基本上,这意味着由于您从Client 继承,因此每个FunctionCall 对象也将是Client 对象,并且由于每个Client 对象都必须是QDialog 对象,因此FunctionCall 对象必须是QDialog 对象。

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

【讨论】:

不,这真的不是我想要的。在我更改代码之前,我所拥有的是 Client 是基类,而 MainWindow 和 ChatWindow 仅继承自它。但这不起作用,因为它创建了一个类的两个实例,并且每次我调用一个函数时都会重置一个新函数。

以上是关于c ++是不是可以继承一个类,但不能继承该类的继承? (qt)的主要内容,如果未能解决你的问题,请参考以下文章

面向对象2

多级继承 C++

visual studio 2010自定义类继承CString问题

自定义异常

java中私有的属性、静态成员可以被子类继承吗?

笔记:枚举类型