[Solved] Operator auf Vektoren Dyadisches Produkt



  • Hallo

    Warum ist folgendes nicht möglich?
    Vektor.h

    #pragma once
    #include "RMatrix.h"
    class Vektor
    {
    public:
    	int n;
    	double *a;
    	Vektor();
    	~Vektor();
    
    	// Skalarprodukt
    	Vektor operator+(Vektor &b);
    	Vektor operator-(Vektor &b);
    };
    

    Zeilenvektor.h

    #pragma once
    #include "Vektor.h"
    #include "SpaltenVektor.h"
    
    class ZeilenVektor :
    	public Vektor
    {
    public:
    	ZeilenVektor();
    	~ZeilenVektor();
    
    	double operator*(ZeilenVektor &b);
    	RMatrix operator*(SpaltenVektor &b);
    };
    

    Spaltenvektor.h

    #pragma once
    #include "Vektor.h"
    #include "ZeilenVektor.h"
    
    class SpaltenVektor :
    	public Vektor
    {
    public:
    	SpaltenVektor();
    	~SpaltenVektor();
    
    	double operator*(SpaltenVektor &b);
    	RMatrix operator*(ZeilenVektor &b);
    };
    

    Wie kann ich es doch zum laufen bringen? Der Compiler meldet:
    Zeile 13 ZeilenVektor.h error C2061: Syntaxfehler: Bezeichner 'SpaltenVektor'
    Zeile 13 SpaltenVektor.h error C2061: Syntaxfehler: Bezeichner 'ZeilenVektor'
    so als wären die Dateien nicht eingebunden.

    Ist es sinnvoller #ifndef _ABC #define #endif zu nutzen anstelle von #pragma once ?

    Danke im Vorraus



  • Du hast eine zyklische Abhängigkeit und der Include Guard wird deshalb Probleme machen.
    Lösung: Forwärtsdeklaration zum Brechen der Abh.:

    class A; // jetzt kannst du den Namen A in z.B. Zeigern o. Referenzen benutzen
    
    class B {
       void fun(A&);
    };
    
    class A { };
    

    Edit: Danach kannst du den Include des jeweils anderen Vektors streichen, da du in den Headern sowieso keine Klassendefinitionen der anderen Klassen brauchst, sondern nur die Namen.



  • Jodocus schrieb:

    Du hast eine zyklische Abhängigkeit und der Include Guard wird deshalb Probleme machen.
    Lösung: Forwärtsdeklaration zum Brechen der Abh.:

    class A; // jetzt kannst du den Namen A in z.B. Zeigern o. Referenzen benutzen
    
    class B {
       void fun(A&);
    };
    
    class A { };
    

    Edit: Danach kannst du den Include des jeweils anderen Vektors streichen, da du in den Headern sowieso keine Klassendefinitionen der anderen Klassen brauchst, sondern nur die Namen.

    Jupp.

    Ich habe gute Erfahrungen gemacht mit

    //Datei B.hpp
    #ifndef B_HPP_INCLUDED_a672ef7bac5bf2e9b1b861fc374778ad
    #define B_HPP_INCLUDED_a672ef7bac5bf2e9b1b861fc374778ad //edit: vorhin vergessen
    #pragma once
    
    class A; // B muss leider A ein wenig kennen
    
    class B {
       void fun(A&);
    };
    
    #include "A.hpp" //Trick 17
    
    #endif
    


  • Das funktioniert leider auch nicht so richtig. Wenn ich die Klassen verwenden möchte wird von einer immer nur die Leere Klasse verwendet, je nachdem welche Datei ich zuletzt einbinde.

    Jedoch habe ich nach kurzem Überlegen festgestellt, dass das Produkt SpaltenMatrix * Zeilenmatrix nur im eindimensionalen Fall Sinn macht und so das Problem beseitigt werden kann.



  • Nerva schrieb:

    Das funktioniert leider auch nicht so richtig. Wenn ich die Klassen verwenden möchte wird von einer immer nur die Leere Klasse verwendet, je nachdem welche Datei ich zuletzt einbinde.

    Was für eine "leere" Klasse?

    class XYZ;
    

    ist keine leere Klasse, sondern die Deklaration (Bekanntmachung für den Compiler) einer Klasse (die so groß sein kann, wie sie will).

    Mir scheint eher, du machst was falsch.



  • Ja richtig ich habe etwas falsch gemacht und zwar habe ich die Klasse wie ich es gewohnt war mit Klammern angegeben und nicht ohne.

    Danke 🙂



  • volkard schrieb:

    //Datei B.hpp
    #ifndef B_HPP_INCLUDED_a672ef7bac5bf2e9b1b861fc374778ad
    #pragma once
    [...]
    #endif
    

    Hm, hier vermischst du zwei Philosophien. Entweder Include Guards und dann richtig, oder pragma once. Dein ifndef bringt dir ohne define gar nichts, das kannst du genauso gut weglassen. Das pragma once ist eher bei Objective C bzw. bei Apple üblich.



  • Nenne einen der "großen" Compiler, die #pragma once nicht verstehen ?!



  • Skym0sh0 schrieb:

    Nenne einen der "großen" Compiler, die #pragma once nicht verstehen ?!

    Falls das an mich gerichtet war: Im Gegenteil, ich gehe davon aus, dass so gut wie alle modernen Compiler das verstehen. Was an "bei ... üblich" hast du nicht verstanden?

    Bei C++ werden meistens halt Include Guards mittels ifndef/define/endif benutzt, mehr habe ich nicht ausgesagt.

    Dass das ifndef/endif ohne define bzw. bei pragma once sinnlos ist, wirst du wohl einsehen, oder?

    Kein Grund, gleich durch die Decke zu gehen.



  • oenone schrieb:

    Kein Grund, gleich durch die Decke zu gehen.

    Oo Tu ich doch gar nicht 😕 . Du jedoch schon eher... 🙄

    Klar, gewöhnlich sieht man die #if-#define Kaskade. Aber z.B. ist bei MSVC projekten das #pragma once voreingestellt.

    Dass die eine Hälfte mit dem anderen nicht funktioniert, ist vollkommen klar. (Wobei das beides keine Philosophien sind, aber das ist jetzt Haarspalterei.)



  • Mach doch die Vorwarddekl besser bei der entsprechenden Klasse, so hat man alles schoen beisammen und musst dir keine Gedanken um vorward dekls wo anders machen.

    #ifndef DINGSBUMS
    #define DINGSBUMS 1
    
    class Spaltenvektor;
    
    #include "Zeilenvektor.h"
    
    class Spaltenvektor 
    {
    // ...
    };
    
    #endif /* DINGSBUMS */
    

  • Mod

    ScottZhang schrieb:

    Mach doch die Vorwarddekl besser bei der entsprechenden Klasse, so hat man alles schoen beisammen und musst dir keine Gedanken um vorward dekls wo anders machen.

    #ifndef DINGSBUMS
    #define DINGSBUMS 1
    
    class Spaltenvektor;
    
    #include "Zeilenvektor.h"
    
    class Spaltenvektor 
    {
    // ...
    };
    
    #endif /* DINGSBUMS */
    

    Das ist kein robuster Ansatz. Spaltenvektor kann nicht wissen, ob die Definition von Zeilenvektor von der Definition von Spaltenvektor abhängt.



  • oenone schrieb:

    volkard schrieb:

    //Datei B.hpp
    #ifndef B_HPP_INCLUDED_a672ef7bac5bf2e9b1b861fc374778ad
    #pragma once
    [...]
    #endif
    

    Hm, hier vermischst du zwei Philosophien. Entweder Include Guards und dann richtig, oder pragma once. Dein ifndef bringt dir ohne define gar nichts, das kannst du genauso gut weglassen. Das pragma once ist eher bei Objective C bzw. bei Apple üblich.

    define hab ich schlicht vergessen.
    ifndef plus pragma stört nicht, soll der leser sich aussuchen, welches er nimmt oder beide lassen.



  • camper schrieb:

    ScottZhang schrieb:

    Mach doch die Vorwarddekl besser bei der entsprechenden Klasse, so hat man alles schoen beisammen und musst dir keine Gedanken um vorward dekls wo anders machen.

    #ifndef DINGSBUMS
    #define DINGSBUMS 1
    
    class Spaltenvektor;
    
    #include "Zeilenvektor.h"
    
    class Spaltenvektor 
    {
    // ...
    };
    
    #endif /* DINGSBUMS */
    

    Das ist kein robuster Ansatz. Spaltenvektor kann nicht wissen, ob die Definition von Zeilenvektor von der Definition von Spaltenvektor abhängt.

    Wenn beide Definitionen gegenseitig voneinander abhängen…
    Jo, das merkt man dann un repariert es.


  • Mod

    volkard schrieb:

    camper schrieb:

    ScottZhang schrieb:

    Mach doch die Vorwarddekl besser bei der entsprechenden Klasse, so hat man alles schoen beisammen und musst dir keine Gedanken um vorward dekls wo anders machen.

    #ifndef DINGSBUMS
    #define DINGSBUMS 1
    
    class Spaltenvektor;
    
    #include "Zeilenvektor.h"
    
    class Spaltenvektor 
    {
    // ...
    };
    
    #endif /* DINGSBUMS */
    

    Das ist kein robuster Ansatz. Spaltenvektor kann nicht wissen, ob die Definition von Zeilenvektor von der Definition von Spaltenvektor abhängt.

    Wenn beide Definitionen gegenseitig voneinander abhängen…
    Jo, das merkt man dann un repariert es.

    Womit das sich-keine-Gedanken-machen-müssen widerlegt wäre.



  • camper schrieb:

    ScottZhang schrieb:

    Mach doch die Vorwarddekl besser bei der entsprechenden Klasse, so hat man alles schoen beisammen und musst dir keine Gedanken um vorward dekls wo anders machen.

    #ifndef DINGSBUMS
    #define DINGSBUMS 1
    
    class Spaltenvektor;
    
    #include "Zeilenvektor.h"
    
    class Spaltenvektor 
    {
    // ...
    };
    
    #endif /* DINGSBUMS */
    

    Das ist kein robuster Ansatz. Spaltenvektor kann nicht wissen, ob die Definition von Zeilenvektor von der Definition von Spaltenvektor abhängt.

    Stimmt auch wieder, ist irgendwie auch nicht besser.

    Edit: Obwohl, so bleibt wenigstens die Abhängigkeit vom Header erhalten, kann ja beim compilieren auch ne Rolle spielen.


Anmelden zum Antworten