Problem mit cast operatoren



  • Ich teste gerade etwas mit Cast operatoren ehrum um für eine größere Klasse welche zur verfügung zu stellen und stoße da auf einige Probleme. Hier erstmal der Testcode:

    class My
    {
    public:
    	int i;
    	My(int _i)
    	{
    		i=_i;
    	};
    	operator int&()
    	{
    		return i;
    	};
    	operator int() const
    	{
    		return i;
    	};
    	operator int*()
    	{
    		return &i;
    	};
    };
    
    void testfunc(int *i)
    {
    	(*i)+=10;
    };
    void testfunc2(int &i)
    {
    	i+=10;
    };
    void testfunc3(int i)
    {
    	i+=10;
    };
    void testfunc4(const My &t,My &t2)
    {
    	int i=t;//ruft operator int() const auf
    	const int &j=t;//ruft operator int() const auf
    	const int &l=t2;//ruft operator int&() auf
    	t2.i+=10;
    	cout<<t2.i<<endl;
    	cout<<t.i<<endl;;
    	cout<<j<<endl;
    	int &k=t2;//ruft oeprator int& () auf
    	k+=10;
    	cout<<t2.i<<endl;
    	t2.i+=10;
    	cout<<k<<endl;
    	cout<<l<<endl;
    };
    
    int main()
    {
    	My t(10);
    	cout<<t.i<<endl;
    	cout<<endl;
    	testfunc(t);//ruft operator int* () auf
    	cout<<t.i<<endl;
    	testfunc2(t);//ruft operator int& () auf
    	cout<<t.i<<endl;
    	testfunc3(t);//ruft operator int& () auf
    	cout<<t.i<<endl;
    	cout<<endl;
    	testfunc4(t,t);//übergabe einmal als const & und einmal als & zum testen
    
    	cin.get();
    };
    

    Ich habe mal alle Stellen wo die Operatoren genutzt werden mit Kommentaren versehen. Probleme machen mir diese beiden Stellen:

    testfunc3(t);//ruft operator int& () auf
    

    An dieser stelle würde auch ein Aufruf eines operators int() reichen, das Problem ist wenn ich

    operator int();
    operator int&();
    

    in der Klasse habe meckertd er Compiler, meine Frage ist wieso? Da die Funktion doch ein int erwartet wäre hier doch ganz klar operator int() vorzuziehen?

    const int &j=t;//ruft operator int() const auf
    

    Diese Stelle ist mein 2. Problem. Hier hätte ich gerne eine const Referenz auf das i in t, ich bekomme jedoch den operator nicht so hin das es funktioniert, wie müsste der Operator hier beschaffen sein?

    Und eine Allgemeine Frage noch, sollte man solche Cast Operatoren einsetzen, oder solte man das ganze lieber über normale Methoden regeln die aussagekräftige Namen haben und bei denen man eher sagen kan was man genau haben möchte?



  • Xebov schrieb:

    Und eine Allgemeine Frage noch, sollte man solche Cast Operatoren einsetzen, oder solte man das ganze lieber über normale Methoden regeln die aussagekräftige Namen haben und bei denen man eher sagen kan was man genau haben möchte?

    Ja. Implizite Konvertierungsoperatoren sollten wirklich nur selten und mit Bedacht eingesetzt werden. Besonders in deinem Falle, wo es noch zu Mehrdeutigkeiten kommt.

    Eine Referenz zurückzugeben ist im Allgemeinen eine schlechte Idee (von Index-Zugriffen etc. mal abgesehen), da du damit direkten Zugriff auf Membervariablen ermöglichst. Warum willst du überhaupt Konvertierungsoperatoren? Um dir die Überladung eigener arithmetischer Operatoren zu sparen?



  • Nexus schrieb:

    Eine Referenz zurückzugeben ist im Allgemeinen eine schlechte Idee (von Index-Zugriffen etc. mal abgesehen), da du damit direkten Zugriff auf Membervariablen ermöglichst. Warum willst du überhaupt Konvertierungsoperatoren? Um dir die Überladung eigener arithmetischer Operatoren zu sparen?

    Nein, ich will sie zur Übergabe benutzen. Die Cast Operatoren sind in etwas komplexerer Form für eine Matrix und Vector Klasse bestimmt um auf die DX Äquivalente zu casten. Zur Zeit nutze ich dafür noch einen reinterpret_cast, der auch sehr gut Funktioniert, weil beide die Variablen in gleicher Anordnung beherbergen. Ich finde den reinterpret_cast aber nicht so schön, deswegen probiere ich hier mit den Cast Operatoren herum um zu schaun wie gut die sich eignen und wieviel Kontrolle man da bekommt, oder eben ob sich eine extra Funktion für das Umcasten lohnt.



  • Xebov schrieb:

    Nein, ich will sie zur Übergabe benutzen.

    Entweder du bietest operator int oder aber du bietest operator int& an. Nicht beides.

    Die Cast Operatoren sind in etwas komplexerer Form für eine Matrix und Vector Klasse bestimmt um auf die DX Äquivalente zu casten. Zur Zeit nutze ich dafür noch einen reinterpret_cast, der auch sehr gut Funktioniert, weil beide die Variablen in gleicher Anordnung beherbergen. Ich finde den reinterpret_cast aber nicht so schön, deswegen probiere ich hier mit den Cast Operatoren herum um zu schaun wie gut die sich eignen und wieviel Kontrolle man da bekommt, oder eben ob sich eine extra Funktion für das Umcasten lohnt.

    Dann hast du einen operator T
    idR gibt es keinen grund einen operator T& anzubieten. Da man sowieso nie referenzen auf interne daten aus der hand gibt. Du kannst dann naemlich nicht mehr garantieren dass deine klasse in korrektem zustand ist.

    uU willst du aber auch von den bestehenden klassen ableiten...



  • Nein nen operator &T brauche ich nicht. Ableiten fidne ich nicht so toll, da ich ja aus daten ableiten müsste über die ich keine Kontrolle habe. Ich geb dir mal ein Beispiel das du verstehst was ich meine.

    //Meine Matrix Klasse:
    class matrix
    {
    public:
        union
        {
            struct
            {
                float m11-m44;
            };
            D3DMATRIX d3dMatrix;
        };
        //Funktionen etc
    };
    //DX struct Matrix
    struct D3DMATRIX
    {
        float m11-m44;
    };
    

    So sieht das Intern aus. Was ich nun will ist ganz einfach, eine Funktion die eine D3DMATRIX erwartet soll auch eine Matrix von mir nehmen können. Das ganze berwerkstellige ich zzt mit einem reinterpret_cast (DX nimmt meist ja Zeiger).
    Hier wolte ich mit einem Cast ansetzen so das der reinterpret_cast sich erübrigt, da ich ihn auch nicht so toll finde. Das mit dem int oben ist nur ein einfaches Testbeispiel um zu sehen was mit den Cast Operatoren Möglich ist. Aber ich denke um das zu bewerkstelligen wäre das beste wohl ein paar Funktionen zu Deffinieren die entsprechende Referenzen usw ausgeben können.



  • mal davon abgesehen dass die union ein ziemlicher bloedsinn ist.
    wo genau ist mit einem operator T das problem?

    Es wirkt so als koenntest du problemlos eine D3MATRIX als member haben. der operator T bzw. operator T* wohl dann eher wenn dauernd ein zeiger gefordert wird liefert den member.

    das ist die haessliche variante, die aber die schnelle ist.

    oder hat deine klasse eigenen state auch noch? so wie ich das verstehe ist das nur ein wrapper um D3MATRIX um ein paar methoden anzubieten damit die syntax schoener ist, oder?



  • Shade Of Mine schrieb:

    mal davon abgesehen dass die union ein ziemlicher bloedsinn ist.

    Wieso hälste das union für Blödsinn? Es ermöglicht zugriff auf verschiedene Art und weisen.

    Shade Of Mine schrieb:

    wo genau ist mit einem operator T das problem?

    Es wirkt so als koenntest du problemlos eine D3MATRIX als member haben. der operator T bzw. operator T* wohl dann eher wenn dauernd ein zeiger gefordert wird liefert den member.

    das ist die haessliche variante, die aber die schnelle ist.

    Das mit dem brauch ich nciht aus dem letzten Post war ein Missverständniss hatte da was falsch interpretiert. D3DMATRIX als Member zu haben ist besser als erben, wenn man die Klasse anderweitig einsetzen will kommt er raus aus dem union und die Klasse bleibt wie vorher auch voll Funktionstüchtig.

    Das Problem mit den cast operatoren das ich habe beruht auf verschiedenen Zugriffen, die Matrix kann ja const ode rnicht const sein, ich brauche zwar meist einen Zeiger, aber wenn ich mal ne Referenz brauche wäre es ja nett wenn alles jederzeit funktioniert, deswegen habe ich auch das Testcase gebaut, um erstmal zuschaun was wie geht, deswegen bin ich mir auch so unsicher ob sich der Einsatz solcher Operatoren insgesammt lohnt.

    Shade Of Mine schrieb:

    oder hat deine klasse eigenen state auch noch? so wie ich das verstehe ist das nur ein wrapper um D3MATRIX um ein paar methoden anzubieten damit die syntax schoener ist, oder?

    Die Klasse ist eigenständig und soll DX fähig sein, aber eben kein direkter Wrapper, deswegen ja auch das union so das sie auch lauffähig bleibt ohne das man mit DX arbeitet.

    EDIT:

    OK ich hab den Knoten jetzt nach einigem rumprobieren raus. Hatte dich da etwas falsch verstanden.


Log in to reply