Nowe klasy bazujące na QIODevice mają te same metody

0

Witam,

Potrzebuję dorobić kilka nowych metod na wszystkie klasy nowo stworzone bazujące na QIODevice.
Poniżej przedstawiam najbardziej uproszczony kod który obrazuje problem:

#include <QCoreApplication>
#include <QFile>


class QIODeviceExtend{
public:
    //virtual qint64 write(const char *data);
    void test(){
        write("test"); // jak to odpalic?
    }
};

class QFileExtend: public QFile, public QIODeviceExtend
{
public:

};

int main(){
    QFileExtend f;
    f.setFileName("out.txt");
    f.open(QIODevice::WriteOnly);

    f.test();

    f.close();
    return 0;
}

Chciałbym móc pisać nowe klasy, bazujące na QFile, QSerialPort itp, które posiadają dodatkowe metody(tak samo działające w każdej klasie), które np. wpisują tekst "test".
Metody będą wyglądać tak samo, więc nie chciałbym kopiować i wklejać w każdą nową stworzoną klasę - chcę uniknąć zbędnego klepania kodu.

Jak taki cel osiągnąć?

0

Udało się, niestety jest to dość ryzykowne zagranie:

#include <QCoreApplication>
#include <QFile>

class QIODeviceExtend
{
public:
    void test(){
        QIODevice * p = reinterpret_cast<QIODevice *>(this);
        p->write("test");
    }
};

class QFileExtend: public QIODeviceExtend, public QFile
{
public:

};

class QDevil: public QIODeviceExtend{

};

int main(){
    QFileExtend f;
    f.setFileName("out.txt");
    f.open(QIODevice::WriteOnly);
    f.test();

    f.close();

    QDevil devil;
    devil.test();
    return 0;
}

Jak widać, klasa QDevil wysypie program, wolałbym errora przy kompilacji...

0
#include <QCoreApplication>
#include <QFile>
 
 
class QIODeviceExtend{
private:
    QIODevice &file;
public:
    QIODeviceExtend(QIODevice *f) : file(*f) {}
    void test(){
        file.write("test");
    }
};
 
class QFileExtend: public QFile, public QIODeviceExtend
{
public:
    QFileExtend() : QIODeviceExtend(this) {}
};
 
int main(){
    QFileExtend f;
    f.setFileName("out.txt");
    f.open(QIODevice::WriteOnly);
 
    f.test();
 
    f.close();
    return 0;
}

Nic lepszego raczej nie wymyślisz.

0
mwl4 napisał(a):
#include <QCoreApplication>
#include <QFile>
 
 
class QIODeviceExtend{
private:
    QIODevice &file;
public:
    QIODeviceExtend(QIODevice *f) : file(*f) {}
    void test(){
        file.write("test");
    }
};
 
class QFileExtend: public QFile, public QIODeviceExtend
{
public:
    QFileExtend() : QIODeviceExtend(this) {}
};
 
int main(){
    QFileExtend f;
    f.setFileName("out.txt");
    f.open(QIODevice::WriteOnly);
 
    f.test();
 
    f.close();
    return 0;
}

Nic lepszego raczej nie wymyślisz.

Problem jest taki, że potrzebuje klasy QFileExtend, QSerialPortExtend itp.
Klasy te będą automatycznie wybierać plik/port i dodatkowo mieć metodę "test" (tych dodatkowych metod będzie ponad 30 - będą dodatkami do pewnego protokołu)

Więc niestety Twój sposób troszkę mija się z celem :(

2

Nie do końca rozumiem. Może takie coś?

template<typename T>
class Extended : public T
{
public:

	using T::T;

	void test(){
		this->write("test");
	}
};

i

auto main() -> int
{
	Extended<QBuffer> blah;
	blah.open(QIODevice::WriteOnly);
	blah.test();
	DBG(blah.data().constData());
}
2
MrClass napisał(a):

Chciałbym móc pisać nowe klasy, bazujące na QFile, QSerialPort

Po pierwsze nadużywanie dziedziczenia to samo zło (tak jak w tym wypadku), kompozycja jest bardziej uniwersalna i unika się wielu dziwnych problemów.

Po drugie jest to niewykonalne z technicznego punktu widzenia. Dokumentacja Qt stwierdza, że:

  • klasa może dziedziczyć tylko po jednym QObject na raz!
  • jeśli dziedziczysz po klasie która jest QObject musi ona wystąpić pierwsza na liście dziedziczenia
    Linka do tych reguł nie chce mi się szukać

Radzę opisać jaką funkcjonalność chcesz uzyskać, a dostaniesz radę jak to prawidłowo rozwiązać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1