2011-12-20 32 views
34

Tôi đang cố gắng sử dụng kết hợp trong các lớp cho C++/Qt để cung cấp một loạt các widget với một giao diện chung. Giao diện được định nghĩa theo cách sao cho nếu nó được định nghĩa là lớp cơ sở cho các lớp widget khác, thì chính widget sẽ có các tín hiệu đó. tức là tham khảo dưới đây.QObject Multiple Inheritance

class SignalInterface: public QObject { 
    Q_OBJECT 

    public: 
    SignalInterface(); 
    virtual ~SignalInterface(); 

    signals: 
    void iconChanged(QIcon); 
    void titleChanged(QString); 
} 

class Widget1: public SignalInterface, QWidget{ 

    public: 
    Widget1() 
    virtual ~Widget1() 

    // The Widget Should Inherit the signals 
} 

Nhìn vào hệ thống phân cấp lớp các vấn đề trở nên rõ ràng, tôi đã vấp vào viên kim cương đáng sợ trong Nhiều Inheritance, nơi WIDGET1 kế thừa từ QWidget, và SignalInterface, và cả hai mà kế thừa từ QObject. Điều này có gây ra bất kỳ vấn đề nào không?

Chúng tôi biết rằng vấn đề này có thể dễ dàng được giải quyết nếu lớp QObject là ảo thuần túy (không phải như vậy).

Một giải pháp có thể sẽ là

class Interface: public QWidget { 
Q_OBJECT 

signals: 
void IconChanged(QIcon); 
void titleChanged(QString); 
} 

class Widget1: public Interface { 

} 

Vấn đề ở đây là tôi đã có rất nhiều mã mà kế thừa từ QWidget, và nó đau đớn để hack rằng trong. Có một cách khác?

+0

Hãy xem: http://stackoverflow.com/questions/17943496/declare-abstract-signal-in-interface-class/17943699#17943699 –

Trả lời

42

Thật không may khi thừa kế QObject hai lần sẽ gây ra sự cố trong moc.

Từ http://qt-project.org:

Nếu bạn đang sử dụng đa kế thừa, moc giả định rằng các lớp được thừa kế thứ nhất là một lớp con của QObject. Ngoài ra, hãy đảm bảo rằng chỉ có lớp được kế thừa đầu tiên là QObject.

Tôi khuyên bạn nên sử dụng cái gì đó giống như mẫu đại biểu hoặc tạo lại bằng HasA chứ không phải mối quan hệ IsA.

5

Qt cho phép đa thừa kế nếu lớp cơ sở kế thừa riêng từ QObject.

Ví dụ:

class Base: private QObject { 
    Q_OBJECT 
    /*Can use signals and slots like any other QObject-derived class*/ 
}; 

class Derived1: public Base { 
    /*Cannot use signals/slots because it does not "see" that Base inherits from QObject*/ 
}; 

class Derived2: public QWidget, public Base { 
    Q_OBJECT 
    /*Can use signals/slots plus has all the functionality of QWidget and Base*/ 
}; 

Tất nhiên, thừa kế tư nhân là một động vật hoàn toàn khác và có thể không cung cấp cho bạn các giải pháp bạn thực sự cần. Những gì tôi sử dụng nó là khi tôi có thể lấy đi bằng cách sử dụng tín hiệu/khe chỉ trong lớp cơ sở. Khi tôi thực sự cần hành vi QObject trong lớp có nguồn gốc, tôi kế thừa từ QObject dành riêng cho chỉ lớp đó.

+0

Sử dụng Qt5.9, giải pháp này có lỗi khi biên dịch tệp được tạo: 'static_cast': chuyển đổi không rõ ràng từ 'QObject *' thành 'myClass *' –