(abstrakte) Basisklasse mit Konstruktor?



  • Hallo,

    ich wundere mich gerade warum es nicht geht bei einer basisklasse einen konstruktor zu setzen in dem ich member habe.

    Ich möchte folgendes schaffen

    class Base
    {
         public:
              Base(int a) {m_a = a;}
              int m_a;
    };
    
    class D1 : public Base
    {
         public:
              //ausgabe von a aus base?
              void foo() { std::cout << a << std::endl; }
    };
    
    //in der main:
    Base* base;
    base = new Base(4);
    
    if (a == 0) base = new D1();
    else base = new D2();
    
    base->foo();
    
    delete base;
    


  • void foo() { std::cout << m_a << std::endl; }
    

    ?



  • Was ist D2? Was ist a bei if(a == 0)? Warum wirfst du dein Base-Objekt weg, bei dem du m_a auf 4 gesetzt hast?



  • die main ist ja auch iwie komplett falsch 😕

    //in der main: 
    Base* base; 
    base = new Base(4); //das hier wird nie wieder gelöscht - und völlig zu unrecht konstruiert
    
    if (a == 0) base = new D1();
    else base = new D2(); 
    
    base->foo(); 
    
    delete base;
    

    so heir wär es richtig:

    Base* bar = new D1(4);
    bar->foo();
    delete bar;
    

    kommen wir zu D1:

    class D1 : public Base
    {
    public:
      D1(int a)
      : Base(a)
      {}
    
      void foo()
      { //wurde ja schon gesagt, dass hier m_a stehen sollte ;o)
        std::cout << m_a << std::endl;
      }
    };
    

    das hinter dem Doppelpkt. im Konstruktor nennt sich Initialisierungsliste, und die solltest du auch bei Base schon nutzen:

    Base::Base(int a)
    : m_a(a)
    {}
    

    Evtl. willst du auch ein Basis-Objekt übergeben? So sieht dein Code zumindest aus, dann:

    struct base
    {
      base(int a)
      : a(a)
      {}
    
    private:
      int a;
    };
    
    struct derived : base
    {
      derived(const base& b)
      : base(b)
      {}
    
      void print()
      {
        std::cout << a << std::endl;
      }
    };
    
    int main()
    {
      base b(4);
      base* d = new derived(b);
    
      d->print();
    
      delete d;
    }
    

    alles klar? : >

    bb

    PS: Lass dich von den struct nicht verwirren, das erspart mir nur die ganzen public s, die ich bei der Verwendung von class hätte mitschreiben müssen ;o)



  • hmm....danke erstmal für die Antwort.

    Also was ihc machen will ist: Ich möchte auf den member in der basis-klasse zugreifen UND aber dann auch in den abgeleiteten. Also so in etwa:

    #include <iostream>
    
    class base
    {
    public:
      base(int a)
      : ba(a)
      {}
    
     virtual void bar() = 0;
    
      void foo() {
           // mach was mit ba in der basisklasse
           std::cout << ba << std::endl;
           bar();
      }
    
      int ba;
    };
    
    class derived : base
    {
    public:
    
      void bar()
      {
        // Hier auch auf den member von base zugreifen
        std::cout << ba << std::endl;
      }
    };
    
    int main()
    {
      base b(4);
      base* d = new derived(b);
    
      d->print();
    
      delete d;
    }
    


  • Ok. Also folgender code funktioniert. Mir ist aber nicht klar warum....

    kann mri jemand helfen?

    #include <iostream>
    
    class base
    {
    public:
       base(int a) : base_a(a) {}
    
      virtual void print() = 0;
    
      int base_a;
    };
    
    class derived : public base
    {
    public:
       derived(int a) : base(a) {}
    
      void print()
      {
        std::cout << base_a << std::endl;
      }
    };
    
    int main()
    {
      base* d = new derived(4);
    
      d->print();
    
      delete d;
    }
    


  • Und warum geht folgendes nicht ? Ich würde gerne eine OBjekt Ctest mit einem übergebenen parameter initialisieren:

    #include <iostream>
    
    class Pattern
    {
        public:
                Pattern(int a) { memb = a;}
    
        int memb;
    };
    class Ctest
    {
            public:
                    Ctest(Pattern* P) : PC(P) { }     
    
                    Pattern* PC;
    };
    class base
    {
    public:
       base(Pattern* P) : P_a(P) {CT = Ctest(P);}
    
      virtual void print() = 0;
       void foo() { std::cout<< "base: " << P_a->memb << std::endl;
           print();
       }
    
      Pattern* P_a;
      Ctest CT;
    };
    
    class derived : public base
    {
    public:
       derived(Pattern* P_) : base(P_) {}
    
      void print()
      {
        std::cout << P_a->memb << std::endl;
      }
    };
    
    int main()
    {
      Pattern * P = new Pattern(3);
      base* d = new derived(P);
    
      d->foo();
      //d->print();
    
      delete d;
    }
    

    Compilermeldung:

    main.cpp:21: Fehler: keine passende Funktion für Aufruf von »Ctest::Ctest()«
    main.cpp:14: Anmerkung: Kandidaten sind: Ctest::Ctest(Pattern*)
    main.cpp:12: Anmerkung:                  Ctest::Ctest(const Ctest&)
    


  • Weil CT nicht in der Initialisierungsliste vom base-Ctor steht, sondern erst im CTor selbst einen Wert bekommt, wird versucht ein Ctest-Objekt mit dem Standard-Ctor zu erzeugen.
    Den gibt es aber nicht, da du ja selber einen Ctor mit Parameter angegeben hast.



  • danke aber wie löse ich dieses Problem?



  • achso also:

    #include <iostream>
    
    class Pattern
    {
        public:
                Pattern(int a) { memb = a;}
    
        int memb;
    };
    class Ctest
    {
            public:
                    Ctest(Pattern* P) : PC(P) { }     
    
                    Pattern* PC;
    };
    class base
    {
    public:
       base(Pattern* P) : P_a(P), CT(P) {}
    
      virtual void print() = 0;
       void foo() { std::cout<< "base: " << P_a->memb << std::endl;
           print();
       }
    
      Pattern* P_a;
      Ctest CT;
    };
    
    class derived : public base
    {
    public:
       derived(Pattern* P_) : base(P_) {}
    
      void print()
      {
        std::cout << P_a->memb << std::endl;
      }
    };
    
    int main()
    {
      Pattern * P = new Pattern(3);
      base* d = new derived(P);
    
      d->foo();
      //d->print();
    
      delete d;
    }
    


  • ich hab nicht die geduld alles durchzulesen - aber die hattest du offenbar ja auch nicht:

    int main() 
    { 
      Pattern * P = new Pattern(3); 
      base* d = new derived(P); 
    
      d->foo(); 
      //d->print(); 
    
      delete d; 
    }
    

    ist nicht besser, als zu vor...

    btw: hör doch bitte mit try&error auf - das klappt mit C++ nicht...
    Lies einfach im Buch deiner Wahl noch mal die Klassen- + Vererbungs-Kapitel durch...

    bb


Anmelden zum Antworten