Problemmeldeung: Kein geeigneter Standartkonstruktor



  • Hallo hab folgendes Problem:
    In meinem Programm kommt die Fehlermeldung: „error C2512: 'IntSet': Kein geeigneter Standardkonstruktor verfügbar „.
    Weiss nicht weiter.Bitte um Hilfe.
    Hier ist die Aufgabenstellung:

    http://www.speedyshare.com/files/23082234/Aufgabe.pdf

    der Fehler taucht in der main-Funktion Zeile 10: IntSet is; auf.

    Und so soll das Programm funktionieren:

    http://www.speedyshare.com/files/23082365/Observer.exe

    Das ist mein Code

    Main-Funktion:
    
    //Die main.cpp muss unverändert bleiben
    #include "intset.h"
    #include "minobserver.h"
    #include "maxobserver.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
       IntSet is;                                   // IntSet-Objekt
       MaxObserver *maxObs = new MaxObserver(&is);  // MinObserver-Objekt
       MinObserver *minObs = new MinObserver(&is);  // MinObserver-Objekt 
       SetIterator setIt(&is);
    
       int element;
       int *elPtr;
       char input[100];
    
       do
       {
         cout << "1 - Insert element\n";
         cout << "2 - Delete element\n";
         cout << "3 - List set\n";
         cout << "4 - Exit\n";
    
         cin >> input;
    	 if (strlen(input) > 1 || input[0] < '1' || input[0] > '4')	
    		 cout << "*** Invalid Option ***\n\n";
    	 else 
    	 {
    	    switch (input[0] - '0')
            {
              case 1:  cout << "Enter an integer number: ";
                       cin >> element;
    				   if (! is.insertElement(element))
                         cout << "Element " << element << " already exists\n";
                       break;
              case 2:  cout << "Enter an integer number: ";
                       cin >> element;
    				   if (! is.removeElement(element))
                         cout << "Element " << element << " not found\n";
                       break;
    	      case 3: setIt.reset(); 
    			      while (elPtr = setIt.next())
                         cout << *elPtr << ' ';
                       cout << '\n';
    		           break;
              case 4:  return 0;
            }
    	    cout << "\n\n";
    	 }
       } while (1);
    
       delete maxObs;
       delete minObs;
       return 0;
    }
    

    Die sequence.h wurde bereitgestellt und muss statt der STL-Bibliothek benutzt werden.Diese darf erweitert werden.

    Sequence.h
    
    #ifndef SEQUENCE_H
    #define SEQUENCE_H
    
    //   Uebung 10.1 Sequentielle Liste
    //   Datei sequence.h
    
    #pragma warning( disable : 4290)  // throw Anweisung
    
    // Exception-Klasse
    class InvalidIndex { };
    
    template<class AD> // AD Typ für Nutzdaten (Application Data)
    class Sequence  {
      AD *seq;        // Speicherplatz
      unsigned max;   // maximale Länge 
      unsigned len;   // aktuelle Länge
      class Iter;
    public:
      Sequence(unsigned n);
      ~Sequence(void);
      unsigned size(void) const;
      bool isEmpty(void) const;
      bool isFull(void) const;
      AD& operator[](unsigned pos) throw (InvalidIndex);
      void pushBack(AD &el); 
      void insert(AD& el);
      bool remove(AD &el);
      void resize(unsigned n);
      AD *linSearch(AD& el) const;
      AD *maxSearch() const;
      AD *minSearch() const;
      typedef Iter iterator;
      iterator begin() { return iterator(seq); }
      iterator end() { return iterator(seq+max); }
    
      friend class IntSet;
    
      class Iter
      {
    		AD* pos;
    	public:
    		Iter(AD* po) { pos = po; }
    		AD& operator*() { return *pos; }
    		Iter operator++(int) { Iter it = *this; pos++; return it; };
    		Iter& operator++() { pos++; return *this; }
    		bool operator==(const Iter& it) { return pos == it.pos; }
    		bool operator!=(const Iter& it) { return pos != it.pos; }
      };
     };
    
    template<class AD> 
    inline Sequence<AD>::Sequence(unsigned n)
    {
    	max = n;
    	seq = new AD[max];
    	len = 0;
    }
    
    template<class AD> 
    inline Sequence<AD>::~Sequence(void)
    {
    	delete seq;
    }
    
    template<class AD> 
    inline unsigned Sequence<AD>::size(void) const
    {
    	return len;
    }
    
    template<class AD> 
    inline bool Sequence<AD>::isEmpty(void) const
    {
    	return len==0;
    }
    
    template<class AD> 
    inline bool Sequence<AD>::isFull(void) const
    {
    	return len==max;
    }
    
    template<class AD> 
    AD& Sequence<AD>::operator[](unsigned pos) throw (InvalidIndex)
    {
    	if (pos+1 > len)  // wg. unsigned-Problem bei (pos < len-1) 
    		throw InvalidIndex();
    	else 
    		return seq[pos];
    }
    
    template<class AD> 
    void Sequence<AD>::pushBack(AD &el)
    { 
    	if (isFull())
    	  resize(max/2); 
    	seq[len] = el;
    	len++;
    }
    
    template<class AD> 
    void Sequence<AD>::insert(AD& el)
    {
    	unsigned pos, i;
    
    	if (isFull())
    	   resize(max/2); 
    	for (pos=0; pos<len; pos++)  // Einfügeposition suchen
    	  if (el < seq[pos])
    		  break;
        for (i=len; i>pos; i--)      // Verschieben
    	    seq[i] = seq[i-1];
    	seq[pos] = el;               // Einfügen
    	len++;
    }
    
    template<class AD> 
    bool Sequence<AD>::remove(AD &el) 
    { unsigned i, j;
    
      for (i=0; i<len; i++)  // Löschposition suchen
      {  if (seq[i] == el)
         {  for (j=i; j<len-1; j++)    // komprimieren
    	      seq[j] = seq[j+1];
    	    len--;  
    		return true;
         }
      }
      return false;
    }
    
    template<class AD>
    void Sequence<AD>::resize(unsigned n)
    {
    	AD* temp = new AD[max+n];
    	for (unsigned i=0; i<len; i++)
    	  temp[i] = seq[i];
    	delete [] seq;
    	seq = temp;
    	max = max + n;
    }
    
    template<class AD> 
    AD *Sequence<AD>::linSearch(AD& el) const
    { unsigned i;
    
      for (i=0; i<len; i++)  
        if (seq[i] == el)
    	   return &seq[i];
      return NULL;
    }
    
    template<class AD>
    AD *Sequence<AD>::maxSearch() const
    {
    	unsigned i;
    	int maxint=0;
    
    	for (i=0; i<len; i++)
    	{
    		if(seq[i] > maxint)
    			maxint = seq[i];
    	}
    	return maxint;
    }
    
    template<class AD>
    AD *Sequence<AD>::minSearch() const
    {
    	unsigned i;
    	int minint=0;
    
    	for (i=0; i<len; i++)
    	{
    		if(seq[i] < minint)
    			minint = seq[i];
    	}
    	return minint;
    }
    
    #endif // SEQUENCE_H
    
    Observer.h
    
    #ifndef OBSERVER_H
    #define OBSERVER_H
    
    class Observer
    {
    	public:
    		virtual void update(void) = 0;
    };
    
    #endif
    
    Subject.h
    
    #ifndef SUBJECT_H
    #define SUBJECT_H
    
    #include "observer.h"
    #include "sequence.h"
    
    typedef Sequence<Observer*> ObsList;
    typedef ObsList::iterator ObsListIterator;
    
    class Subject
    {
    		ObsList obs;
    	public:
    		Subject();
    		void attach(Observer *observer);
    		void detach(Observer *observer);
    		void notify();
    
    };
    
    Subject::Subject()
    {
    }
    
    void Subject::attach(Observer *observer)
    {
    	obs.pushBack(observer);
    }
    
    void Subject::detach(Observer *observer)
    {
    	obs.remove(observer);
    }
    
    void Subject::notify()
    {
    	ObsListIterator beginIt = obs.begin();
    	ObsListIterator endIt = obs.end();
    
    	for( beginIt; beginIt != endIt; beginIt++)
    
    		( *beginIt )->update();
    
    }
    
    #endif
    
    Inset.h
    
    #ifndef INTSET_H
    #define INTSET_H
    
    #include "subject.h"
    #include "sequence.h"
    
    typedef Sequence<int> IntList;
    
    class IntSet:public Subject
    {
    		IntList is;
    	public:
    		IntSet();
    		bool insertElement(int element);
    		bool removeElement(int element);
    		unsigned size();
    
    		friend class SetIterator;
    		friend class MaxObserver;
    		friend class MinObserver;
    };
    
    IntSet::IntSet()
    {
    	unsigned s = 10;
    	is->seq = new int[s];
    }
    
    bool IntSet::insertElement(int element)
    {
    	for(unsigned i=0; i<is.size(); i++)
    		if(is.operator [](i) == element)
    		{	return false;	}
    	is.pushBack(element);
    	notify();
    	return true;
    }
    
    bool IntSet::removeElement(int element)
    {
    	for(unsigned i=0; i<is.size(); i++)
    		if(is.operator [](i) == element)
    		{	is.remove(element);
    			notify();
    			return true;
    		}
    	return false;
    }
    
    unsigned IntSet::size()
    {
    	return is.size();
    }
    
    //*********************//
    //***Iterator-Klasse***//
    //*********************//
    
    class SetIterator
    {
    		IntSet *my_is;
    		unsigned int pos;
    	public:
    		SetIterator(IntSet *s);
    		int *next();
    		void reset();
    };
    
    SetIterator::SetIterator(IntSet *s):pos(0), my_is(s)
    {
    }
    
    int *SetIterator::next()
    {
    	if(pos < my_is->size())
    		return &my_is->is.operator [](pos++);	
    	else
    		return 0;
    }
    
    void SetIterator::reset()
    {
    	pos = 0;
    }
    
    #endif
    
    MaxObserver.h
    
    #ifndef MAXOBSERVER_H
    #define MAXOBSERVER_H
    
    #include "intset.h"
    #include <iostream>
    
    using namespace std;
    
    class MaxObserver:public Observer
    {
    		IntSet *intset;
    		int max;
    		bool a;
    	public:
    		MaxObserver(IntSet *is);
    		~MaxObserver();
    		void update();
    };
    
    MaxObserver::MaxObserver(IntSet *is):intset(is), a(false)
    {
    	intset->attach(this);
    	update();
    }
    
    MaxObserver::~MaxObserver()
    {
    	intset->detach(this);
    	intset = NULL;
    }
    
    void MaxObserver::update()
    {
    	for(unsigned i=0; i<intset->size(); i++)
    		if(intset->is.operator [](i) > max)
    			max=intset->is.operator [](i);
    			cout << "MaxObserver changed to: " << max << endl;
    }
    
    #endif
    
    MinObserver.h
    
    #ifndef MINOBSERVER_H
    #define MINOBSERVER_H
    
    #include "intset.h"
    #include <iostream>
    
    using namespace std;
    
    class MinObserver:public Observer
    {
    		IntSet *intset;
    		int min;
    		bool a;
    	public:
    		MinObserver(IntSet *is);
    		~MinObserver();
    		void update();
    };
    
    MinObserver::MinObserver(IntSet *is):intset(is), a(false)
    {
    	intset->attach(this);
    	update();
    }
    
    MinObserver::~MinObserver()
    {
    	intset->detach(this);
    	intset = NULL;
    }
    
    void MinObserver::update()
    {
    	for(unsigned i=0; i<intset->size(); i++)
    		if(intset->is.operator [](i) < min)
    			min=intset->is.operator [](i);
    			cout << "MinObserver changed to: " << min << endl;
    }
    
    #endif
    

    Hoffe mir kann einer helfen.. 🕶



  • Versuch, den Code zu reduzieren, sodass der Fehler immer noch erhalten bleibt. Und dann poste nochmals wenig Code, der aber vollständig und kompilierbar ist und das Problem immer noch repräsentiert.

    P.S.: Was hat dein Problem mit dem Observer Pattern (Titel) zu tun? Auch wenn du es in deinem Code verwendest, ist es für deinen Fehler irrelevant.



  • Ja, ich weis, dass es "zu viel" Code ist, aber leider weiß ich nicht, wie ich ihn kürzen soll.
    Da alles zusammen hängt....ok ich ändere meinen Titel 😉



  • kasax_a schrieb:

    Ja, ich weis, dass es "zu viel" Code ist, aber leider weiß ich nicht, wie ich ihn kürzen soll.

    Nach und nach Teile auskommentieren und schauen, ob der Fehler immer noch auftritt. Ich weiss, dass es mühsam ist, aber für uns ist es das genauso. Sei froh, dass du es nur mit einem Compilezeit-Fehler zu tun hast. 😉

    Versuch auch mal, alles neu zu kompilieren. Und du bist dir sicher, dass vor der genannten Fehlermeldung nicht noch andere Fehler auftreten?



  • Wenn du die ganze Fehlermeldung gepostet hättest, hätte man dir mehrere Sachen sagen können:
    😉 Sequence hat keinen Standardkonstruktor, der aber benötigt wird für den dein "IntList is;" - außer du initialisierst das Objekt ordentlich via Initialisierungsliste im Konstruktor von IntSet.
    😉 is ist kein Zeigertyp, weshalb dein "is->seq = new int[s];" im IntSet-Konstruktor falsch ist. Wäre mit erstem Punkt korrekt gelöst eh nicht notwendig 😉

    BTW.: Das "friend class IntSet;" im Sequence stammt von dir, oder? Kann mir nicht so ganz denken, dass das vom Prof mitgegegeben wurde.



  • "is->seq = new int[s];" ja ist ein schreibfehler, habe ich bemerkt.

    "friend class IntSet;" ja das stammt von mir, aber ich brauche es so, oder nicht?^^

    aber irgendwie bekomme ich das nicht hin mit dem Konstruktor 😞



  • kasax_a schrieb:

    "friend class IntSet;" ja das stammt von mir, aber ich brauche es so, oder nicht?^^

    Nein, brauchst du nicht. Du kannst dich ja nicht einfach so in fremde Klassen eintragen...

    aber irgendwie bekomme ich das nicht hin mit dem Konstruktor 😞

    Hab ich auch geschrieben: Initialisierungsliste. Wenn du verhindern willst, dass für Basisklassen- oder Elementinitialisierung nicht der Standardkonstruktor verwendet werden soll, musst du das dort erledigen, in deinem Fall ist das die einzige Möglichkeit.
    Und um das "Wo" nochmal hervoruiheben: Bei der Konstruktordefinition von IntSet.



  • soo....ok habe jetzt verändert:

    Intset.h
    
    #ifndef INTSET_H
    #define INTSET_H
    
    #include "subject.h"
    #include "sequence.h"
    
    typedef Sequence<int> IntList;
    
    class IntSet:public Subject
    {
            IntList is;
        public:
            //Kein Konstruktor//
            bool insertElement(int element);
            bool removeElement(int element);
            unsigned size();
    
            friend class SetIterator;
            friend class MaxObserver;
            friend class MinObserver;
    }; 
    [...]
    
    Sequence.h
    
    #ifndef SEQUENCE_H
    #define SEQUENCE_H
    
    //   Uebung 10.1 Sequentielle Liste
    //   Datei sequence.h
    
    #pragma warning( disable : 4290)  // throw Anweisung
    
    // Exception-Klasse
    class InvalidIndex { };
    
    template<class AD> // AD Typ für Nutzdaten (Application Data)
    class Sequence  {
      AD *seq;        // Speicherplatz
      unsigned max;   // maximale Länge
      unsigned len;   // aktuelle Länge
      class Iter;
    public:
      Sequence();  //KEINE PARAMETER//
      ~Sequence(void); 
    [...]
    };
    template<class AD>
    inline Sequence<AD>::Sequence()  //KEINE PARAMETER//
    {
        max = 10;
        seq = new AD[max];
        len = 0;
    }
    

    Nun läuft das Programm, bricht aber ab, sobald sich Minimum und/oder Maximum ändert.



  • DU LIEST NICHT, WAS ICH SCHREIBE!
    Such doch wenigstens mal nach Initialisierungsliste...
    Du veränderst zum wiederholten Male einen Header, der dich NICHTS ANGEHT! Sequence wurde dir bereitgestellt zur Hilfe, und nicht um darin rumzupfuschen!

    Einfach ein kleines Beispiel dazu, wie so eine Elementinitialisierung via Initialisierungsliste ausschaut:

    class Test {
        int member;
        std::string name;
    public:
        Test( int val, const std::string& name );
    };
    
    Test::Test( int val, const std::string& nm )
     : member(val),  // Elementinitialisierer
       name(nm)      // Elementinitialisierer für ne Klasse
    {}
    


  • doch ich lese schon, aber wenn ich über die Initialisierungsliste mache, dann kommt es, dass es kein Standartkonstruktor verfügbar ist.



  • kasax_a schrieb:

    doch ich lese schon, aber wenn ich über die Initialisierungsliste mache, dann kommt es, dass es kein Standartkonstruktor verfügbar ist.

    Zeig bitte den Code, ich kann mir nicht vorstellen, dass du den da hingebastelt hast, wo er hin soll 😉
    Und die zugehörige KOMPLETTE Fehlermeldung bitte auch.



  • ok hier der Code...Sequence.h habe ich jetzt unverändert gelassen..

    fehlermeldung: Fehler 1 error C2512: 'IntSet': Kein geeigneter Standardkonstruktor verfügbar c:\users\user\documents\visual studio 2008\projects\testat\testat\main.cpp 10 Testat

    #ifndef INTSET_H
    #define INTSET_H
    
    #include "subject.h"
    #include "sequence.h"
    
    typedef Sequence<int> IntList;
    
    class IntSet:public Subject
    {
            IntList is;
        public:
            IntSet(IntList s);
            bool insertElement(int element);
            bool removeElement(int element);
            unsigned size();
    
            friend class SetIterator;
            friend class MaxObserver;
            friend class MinObserver;
    };
    
    IntSet::IntSet(IntList s):is(s)
    {
    }
    
    [...]
    


  • class IntSet:public Subject
    {
            IntList is;
        public:
            IntSet(const IntList& s);
            bool insertElement(int element);
            bool removeElement(int element);
            unsigned size();
    
            friend class SetIterator;
            friend class MaxObserver;
            friend class MinObserver;
    };
    
    IntSet::IntSet(const IntList& s):is(s)
    {
    }
    

    Jetzt die Quizfrage: Warum geht das so und wie vorher nicht?

    //EDTI:
    Ok, Typen nicht gesehen. IntSet != IntList. 🙂



  • mhh...ändert sich aber gar nix dran....immer noch die selbe fehlermeldung 😞



  • GRRR, wie hat dein Konstruktor vorher ausgeschaut?
    IntSet(), das ist die Signatur eines Standardkosntruktor. Im Konstruktor hast du dann versucht, die Größe der IntList zu ändern, auf 10 (an allen Funktionen von IntList vorbei).
    Die erwartete Lösung sähe dann so aus:

    IntSet::IntSet()
     : is(10)
    {}
    

    Der Fehler den du jetzt produzierst, rührt daher dass IntSet keinen Standardkonstruktor mehr hat, das "IntSet is;" in der main() löst ihn aus.



  • ok...habe es so gemacht, aber jetzt kommt diese fehlermeldungen:

    1: Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Subject::Subject(void)" (??0Subject@@QAE@XZ)" in Funktion ""public: __thiscall IntSet::IntSet(void)" (??0IntSet@@QAE@XZ)". main.obj Testat

    2: Fehler 2 fatal error LNK1120: 1 nicht aufgelöste externe Verweise. C:\Users\user\Documents\Visual Studio 2008\Projects\Testat\Debug\Testat.exe Testat



  • Es gab in Subject das selbe Problem wie in IntSet, diesmal mit obs. Ich nehme an, du hast versucht dem Problem aus dem Weg zu gehen und hast die Konstruktordefinition gelöscht 😛
    Oder die Implementierung liegt in einer anderen Datei, die nicht mitkompiliert wurde. Jedenfalls ist das kein Compiler-Problem mehr, sondern ein Linkerfehler.



  • japp....habe ich bemerkt und habe jetzt so gemacht:

    ...
        public:
            Subject();
            void attach(Observer *observer);
            void detach(Observer *observer);
            void notify();
    
    };
    
    Subject::Subject():obs(0)
    {
    
    }
    
    ...
    

    das programm läuft, aber nicht ganz richtig....es zeigt MaxObserve und MinObserve nicht an...und wenn ich die "4" zum exit drücke passiert auch nix.



  • Tjo, dann musst du jetzt die nächste Hürde zum fertigen Programm meistern: Debuggen.
    Unter Linux/Mingw nimmst du den gdb, unter VS gibt es sicher auch einen debugger. Verwendung wird in der jeweiligen Doku oder auf diversen Internetseiten in Tutorials oder anderen Foren zur Genüge diskutiert 😉



  • ich kriegs echt nicht hin

    hier ist der Code von MaxObserver und Min Observer

    #ifndef MINOBSERVER_H
    #define MINOBSERVER_H
    
    #include "intset.h"
    #include "sequence.h"
    #include <iostream>
    
    using namespace std;
    
    class MinObserver:public Observer
    {
            IntSet *intset;
            int min;
            bool a;
        public:
            MinObserver(IntSet *is);
            ~MinObserver();
            void update();
    };
    
    MinObserver::MinObserver(IntSet *is):intset(is), a(false)
    {
        intset->attach(this);
        update();
    }
    
    MinObserver::~MinObserver()
    {
        intset->detach(this);
        intset = NULL;
    }
    
    void MinObserver::update()
    {
        for(unsigned i=0; i<intset->size(); i++)
            if(intset->is.operator [](i) < min)
    		{
    			min=intset->is.operator [](i);
                cout << "MinObserver changed to: " << min << endl;
    		}
    }
    
    #ifndef MAXOBSERVER_H
    #define MAXOBSERVER_H
    
    #include "intset.h"
    #include "sequence.h"
    #include <iostream>
    
    using namespace std;
    
    class MaxObserver:public Observer
    {
            IntSet *intset;
            int max;
            bool a;
        public:
            MaxObserver(IntSet *is);
            ~MaxObserver();
            void update();
    };
    
    MaxObserver::MaxObserver(IntSet *is):intset(is), a(false)
    {
        intset->attach(this);
        update();
    }
    
    MaxObserver::~MaxObserver()
    {
        intset->detach(this);
        intset = NULL;
    }
    
    void MaxObserver::update()
    {
        for(unsigned i=0; i<intset->size(); i++)
            if(intset->is.operator [](i) > max)
    		{
                max=intset->is.operator [](i);
    			a = true;
                cout << "MaxObserver changed to: " << max << endl;
    		}
    }
    
    #endif
    

    wie passe ich das jetzt auf meine Sequence.h an?
    das er dann auch die werte aus gibt?


Log in to reply