Sequence Class



  • Hallo,

    Ich muss eine Sequence Klasse bauen, das header-file dafür ist vorgegeben:

    class sequence
        {
        public:
            // TYPEDEFS and MEMBER CONSTANTS
            typedef double value_type;
            typedef std::size_t size_type;
            static const size_type DEFAULT_CAPACITY = 30;
            // CONSTRUCTORS and DESTRUCTOR
            sequence(size_type initial_capacity = DEFAULT_CAPACITY);
            sequence(const sequence& source);
    		~sequence( );
            // MODIFICATION MEMBER FUNCTIONS
    		void resize(size_type new_capacity);
            void start( );
            void advance( ); //set the current_index to the next number in the array
            void insert(const value_type& entry); //insert before the number with the current index
            void attach(const value_type& entry); //insert after the number with the current index
            void remove_current( );
            void operator =(const sequence& source);
            // CONSTANT MEMBER FUNCTIONS
            size_type size( ) const;
            bool is_item( ) const;
            value_type current( ) const;
        private:
            value_type* data; //das array mit den zahlen drinnen
            size_type used; //wieviele zahlen in dem array stehen
            size_type current_index;
    	size_type capacity;
        };
    

    Leider stimmt bei mir beim copy-constructor anscheinend irgendwas nicht, aber ich komme einfach nicht drauf was hier falsch ist:

    sequence::sequence(const sequence& source)
    {
    	data = new value_type[source.capacity];
    	capacity = source.capacity;
    	used = source.used;
    	current_index = source.current_index;
    	copy(source.data, source.data + used, data);
    }
    

    Hier auch noch die insert, attach und resize funktionen:

    void sequence::insert(const value_type& entry)
    {
    	if(used == capacity)
    		resize(used);
    
    	if(!(is_item()))
    		current_index = 0;
    
    	for(int i = used; i > current_index; i--)
    	{
    		data[i] = data[i-1];
    	}
    	data[current_index] = entry;
    	++used;
    }
    
    void sequence::attach(const value_type& entry)
    {
    	if(used == capacity)
    		resize(used);
    
    	if(current_index >= used)
    	{
    		start();
    		advance();
    		advance();
    	}
    	if(used!=0)
    	{
    		for(int i = used; i > current_index+1; i--)
    		{
    			data[i] = data[i-1];
    		}
    		data[current_index+1] = entry;
    		current_index++;
    	}
    	else
    	{
    		data[current_index] = entry;
    	}
    	++used;
    }
    
    void sequence::resize (size_type new_capacity)
    {
    	value_type* larger_array;
    
    	if(new_capacity < used)
    		new_capacity = used;
    
    	larger_array = new value_type[new_capacity];
    	copy(data, data + used + current_index, larger_array);
    	delete[] data;
    	data = larger_array;
    	capacity = new_capacity;
    }
    

    Hat irgendjemand von euch ne Ahnung was hier falsch läuft? - Ich arbeite daran jetzt schon solange daran und bin schon kurz vorm verzweifeln... 😞

    lg matti



  • Hier ist das test-programm, das ich verwende:

    [/code]
    int test5( )
    {
    sequence original; // A sequence that we'll copy.
    double items[2*original.DEFAULT_CAPACITY];
    size_t i;

    // Set up the items array to conatin 1...2DEFAULT_CAPACITY.
    for (i = 1; i <= 2
    original.DEFAULT_CAPACITY; i++)
    items[i-1] = i;

    // Test copying of an empty sequence. After the copying, we change the original.
    cout << "Copy constructor test: for an empty sequence." << endl;
    sequence copy1(original);
    original.attach(1); // Changes the original sequence, but not the copy.
    if (!correct(copy1, 0, 0, items)) return 0;

    // Test copying of a sequence with current item at the tail.
    cout << "Copy constructor test: for a sequence with cursor at tail." << endl;
    for (i=2; i <= 2*original.DEFAULT_CAPACITY; i++)
    original.attach(i);
    cout << "SIZE: " << original.size() << endl;
    sequence copy2(original);
    original.start( );
    original.advance( );
    original.remove_current( ); // Removes 2 from the original, but not the copy.
    if (!correct
    (copy2, 2*original.DEFAULT_CAPACITY, 2*original.DEFAULT_CAPACITY-1, items)
    )
    return 0;

    // Test copying of a sequence with cursor near the middle.
    cout << "Copy constructor test: for a sequence with cursor near middle." << endl;
    original.insert(2);
    for (i = 1; i < original.DEFAULT_CAPACITY; i++)
    original.advance( );
    // Cursor is now at location [DEFAULT_CAPACITY] (counting [0] as the first spot).
    sequence copy3(original);
    original.start( );
    original.advance( );
    original.remove_current( ); // Removes 2 from the original, but not the copy.
    if (!correct
    (copy3, 2*original.DEFAULT_CAPACITY, original.DEFAULT_CAPACITY, items)
    )
    return 0;

    // Test copying of a sequence with cursor at the front.
    cout << "Copy constructor test: for a sequence with cursor near middle." << endl;
    original.insert(2);
    original.start( );
    // Cursor is now at the front.
    sequence copy4(original);
    original.start( );
    original.advance( );
    original.remove_current( ); // Removes 2 from the original, but not the copy.
    if (!correct
    (copy4, 2*original.DEFAULT_CAPACITY, 0, items)
    )
    return 0;

    // Test copying of a sequence with no current item.
    cout << "Copy constructor test: for a sequence with no current item." << endl;
    original.insert(2);
    while (original.is_item( ))
    original.advance( );
    // There is now no current item.
    sequence copy5(original);
    original.start( );
    original.advance( );
    original.remove_current( ); // Removes 2 from the original, but not the copy.
    if (!correct
    (copy5, 2*original.DEFAULT_CAPACITY, 2*original.DEFAULT_CAPACITY, items)
    )
    return 0;
    }
    [/code]

    Nach der Zeile cout << "Copy constructor test: for a sequence with cursor near middle." << endl; bricht das Programm ab und es erscheint ein Popup-Fenster, wo steht, dass das Programm einen Fehler festgestellt hat und beendet werden musste.

    Ich glaube der Fehler passiert eigentlich bei dem insert statement danach.

    Hat jemand von euch ne ahnung..? 😕

    matti



  • mathon schrieb:

    Leider stimmt bei mir beim copy-constructor anscheinend irgendwas nicht, aber ich komme einfach nicht drauf was hier falsch ist:

    sequence::sequence(const sequence& source)
    {
    	data = new value_type[source.capacity];
    	capacity = source.capacity;
    	used = source.used;
    	current_index = source.current_index;
    	copy(source.data, source.data + used, data);
    }
    

    Hallo Matti,
    Der Copy-Konstruktor ist im Prinzip korrekt. Du soltest aber Initialisierungslisten benutzen - also

    sequence::sequence( const sequence& source )
        : data( new value_type[ source.capacity ] )
        , used( source.used )
        , current_index( source.current_index )
        , capacity( source.capacity )
    {
        std::copy( source.data, source.data + used, data );
    }
    

    Aber ..

    mathon schrieb:

    Hier auch noch die insert, attach und resize funktionen:

    void sequence::insert(const value_type& entry)
    {
        if(used == capacity)
            resize(used);
    // ...
    void sequence::attach(const value_type& entry)
    {
    	if(used == capacity)
    		resize(used);
    // ...
    

    hier müßte es doch in beiden Fällen eher

    if(used == capacity)
            resize( 2 * used );   // verdoppeln, um mehr Platz zu schaffen
    

    heißen.

    Weiter soltest Du die 'Regel der Drei' beachten, die da lautet: Wenn ein nicht trivialer Destruktor oder Copy-Konstruktor oder Assignment-operator vorhanden ist, so müssen alle drei implementiert werden. Bei Dir fehlt der Assignment-Operator. Überlege mal was bei ..

    sequence s1;
      s1.attach( 3.14 );
      sequence s2;
      s1 = s2;
    

    .. passiert!

    Btw.: was machen 'is_item()' und 'correct(..)'?

    Gruß
    Werner



  • hi,

    supeerrr! das war der fehler, ich hatte die größe des arrays nicht erhöht. Ich hatte auch den assignment-operator implementiert aber nicht gepostet, weil ich dachte, dass dort der fehler nicht liegen würde...

    hier zur verfollständigung, die anderen methoden:

    sequence::sequence(size_type initial_capacity)
    {
        data = new value_type[initial_capacity];
        capacity = initial_capacity;
        used = 0;
        current_index = 0;
    }
    
    sequence::~sequence()
    {
        delete[] data;
    }
    
    void sequence::operator = (const sequence& source)
    {
        value_type* new_data;
    
        if (this == &source)
            return;
    
        if(capacity != source.capacity)
        {
            new_data = new value_type[source.capacity];
            delete[] data;
            data = new_data;
            capacity = source.capacity;
        }
    
        used = source.used;
        current_index = source.current_index;
        copy(source.data, source.data + used, data);
    }
    
    void sequence::start( )
    {
        current_index = 0;
    }
    
    void sequence::advance( )
    {
        if(is_item())
            current_index++;
    }
    
    void sequence::remove_current( )
    {
        //cout << current_index << " " << used;
        for(int i = current_index; i < used; i++)
        {
            data[i] = data[i+1];
        }
        used--;
    
    }
    
    sequence::value_type sequence::current() const
    {
        return data[current_index];    
    }
    
    bool sequence::is_item( ) const
    {
        if(current_index < used)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    sequence::size_type sequence::size() const
    {
        return used;
    }
    

    DANKE nochmal!!


Anmelden zum Antworten