A strange error with definition and declaration of a member function - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 20 of 20

Thread: A strange error with definition and declaration of a member function

  1. #16
    Join Date
    Jun 2015
    Posts
    99

    Re: A strange error with definition and declaration of a member function

    Hi, here is my current code:

    Code:
    #include <std_lib_facilities_4.h>
    using namespace std;
    
    template<class Elem>
    class Mylist {
    
    public:
    	class Iterator;
    
    	Mylist<Elem>() {       // Constructor
    		sz = 0;
    		first = nullptr;
    		last = nullptr;
    	}
    
    	Mylist& operator=(const Mylist& N) {        // Copy constructor/assignment
    		Mylist<Elem>* l = new Mylist<Elem>;
    		l->sz = this->sz;
    		l->first = this->first;
    		l->last = this->last;
    		N = l;
    	}
    
    	/*~Mylist<Elem>() {
    		for (auto e = first; e != nullptr; ) {
    		auto d = e;
    		e = e->succ;
    		delete d;
    	 }
    	}
    	*/
    	int size() { return sz; }
    
    	Iterator begin();  // iterator to the first element
    	Iterator end();  // iterator to one beyond the last element
    
    	Iterator insert(Iterator p, const Elem& v);  // insert v into the list after p
    	Iterator erase(Iterator p);  // remove p from the list
    
    	void puch_back(const Elem& v);  // insert v at end
    	void push_front(const Elem& v); // insert v at front
    	void pop_front();  // remove the first element
    	void pop_back();  // remove the last element
    
    	Elem& front();  // the first element
    	Elem& back();  // the last element
    
    private:
    	int sz;
    	class Link;
    
    protected:
    	Link* first;
    	Link* last;
    };
    
    //*****************************************
    
    template<class Elem>
    class Mylist<Elem>::Link {
    
    public:
    	Link(Elem v, Link* p = nullptr, Link* s = nullptr) : 
    		val(v), prev(p), succ(s) { }
    
    	Link* prev = nullptr;
    	Link* succ = nullptr;
    	Elem val;
    };
    
    //****************************************
    
    template<class Elem>
    class Mylist<Elem>::Iterator {
    
    private:
      Link* curr;    
    
    public:
    	Iterator(Link* p) : curr(p) {  }
    
    
    	Iterator& operator++() { curr = curr->succ; return *this; } // forward
    	Iterator& operator--() { curr = curr->prev; return *this; } // backward
    
    	Elem& operator*() { return curr->val; } // get value (dereference)
    
    	bool operator==(const Iterator& b) const { return curr == b.curr; }
    	bool operator!=(const Iterator& b) const { return curr != b.curr; }
    };
    
    //****************************************************************************
    
    template<class Elem>
    typename Mylist<Elem>::Iterator Mylist<Elem>::begin()
    {
    	return Iterator(first);
    	
    }
    
    //************************************
    
    template<class Elem>
    typename Mylist<Elem>::Iterator Mylist<Elem>::end()
    {
    	Link* k = last + 1;
    	last->succ = k;
    	k->prev = last;
    	return Iterator(k);
    }
    
    //*************************************************************
    
    template<class Elem>
    typename Mylist<Elem>::Iterator Mylist<Elem>::insert(Iterator p, const Elem& v)
    {
    	p->succ->prev = new Link(v, p, p->succ);
    	p->succ = pp->succ->prev;
    	return p;
    }
    
    //************************************************
    
    template<class Elem>
    typename Mylist<Elem>::Iterator Mylist<Elem>::erase(Iterator p)
    {
    	p->prev = p->succ;
    	p->succ = p->prev;
    	return p;
    }
    
    //*****************************
    
    template<class Elem>
    void Mylist<Elem>::puch_back(const Elem& v)
    {
    	last = (first == nullptr) ? (first = new Link(v)) : (last->succ = new Link(v, last));
    	++sz;
    }
    
    //**************************************************
    
    template<class Elem>
    void Mylist<Elem>::push_front(const Elem& v)
    {
    	first = (last == nullptr) ? (last = new Link(v)) : 
    		(first->prev = new Link(v, nullptr, first));
    	++sz;
    }
    
    //******************************
    
    template<class Elem>
    void Mylist<Elem>::pop_front()
    {
    	Link* d = first;
    	first = first->succ;
    	delete d;
    }
    
    //*********************************
    
    template<class Elem>
    void Mylist<Elem>::pop_back()
    {
    	Link* k = last->prev;
    	last->prev = last->succ;
    	last->succ = last->prev;
    	last = k;
    }
    
    //************************************
    
    template<class Elem>
    Elem& Mylist<Elem>::front()
    {
    	return first->val;
    }
    
    //********************************
    
    template<class Elem>
    Elem& Mylist<Elem>::back()
    {
    	return last->val;
    }
    
    //***************************************************
    
    int main()
    {
    	Mylist<int> l1;
    	l1.puch_back(12);
    	l1.puch_back(15);
    	l1.puch_back(30);
    	l1.push_front(10);
    
    	Mylist<int>l2 = l1;
    
    	cout << l1.size() << ' ' << l2.size() << endl;
    
    	for (auto p1 = l1.begin(); p1 != l1.end(); ++p1)
    		cout << *p1 << ' ';
    	cout << endl;
    
    	for (auto p2 = l2.begin(); p2 != l2.end(); ++p2)
    		cout << *p2 << ' ';
    	cout << endl;
    
    	system("pause");
    	return 0;
    }
    1- When I use the destructor, I encounter an exception. I tried to solve it and changed end() many times but couldn't remove the issue. That is why I made the destructor a comment.

    2- Look at the end() please. When I use it this way, it prints the values fine, but when I replace its code with the one below it faces an error (out of range) at the first printing for loop.
    Code:
     last->succ = new Link(0, last);
    	return Iterator(last->succ);
    3- I also implemented the copy assignment/constructor and other member functions as well. Please take a look at them to see whether they are fine to you or not.

    Thanks.

  2. #17
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,632

    Re: A strange error with definition and declaration of a member function

    3. You have implemented the copy assignment - not the copy constructor. In your code

    Code:
    Mylist<int>l2 = l1;
    This actually uses the copy constructor - not copy assignment - as l2 is being constructed. However, the code for the copy assignment is not right. You are doing a shallow copy - not a deep copy. When dynamic memory is used (as here) you need to do a deep copy rather than a shallow copy. For further info see https://stackoverflow.com/questions/...s-shallow-copy

    1, 2.
    Code:
    	Link* k = last + 1;
    No. With a linked list this is incorrect as there is no allocated memory adjacent to the last element in the list. The succ value in the last element is nullptr so the simplest way to implement end() is to have it return an Iterator for nullptr. See my code in post #15. This is the reason that the destructor doesn't work and you have issues displaying the list.

    Other points

    For member variables, these can be default initialised when they are defined in the class. See my code in post #15 rather than in the default constructor.

    size() begin(), end(), front() and back() should be const.

    The insert code is not correct as it doesn't take into account all possible situations (eg when p->succ is a nullptr or p is a nullptr Iterator) - and doesn't change sz. The code for erase is just incorrect. Walk through the process of erasing a node on paper using diagrams for all possibilities and then you'll see.

    pop_front() leaves a dangling prec pointer for the now first node. What if there is only 1 node in the list? Also sz isn't changed.

    pop_back() doesn't delete the node and doesn't change sz.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

  3. #18
    Join Date
    Jun 2015
    Posts
    99

    Re: A strange error with definition and declaration of a member function

    Thank you. I made many changes but before posting the modified sections, what does "end() points to one beyond the last element", mean please?

    If we implement it like this:
    Code:
    template<class Elem>
    typename Mylist<Elem>::Iterator Mylist<Elem>::end() const
    // iterator to one beyond the last element
    {
    	return Iterator(last->succ);
    }
    it doesn't match the definition said above, because there is no "one" beyond the last. That's why I tried to using a code like below cover the definition:
    Code:
     Link* k = last + 1;
    	last->succ = k;
    	k->prev = last;
    	return Iterator(k);
    And also, it's right that last+1 doesn't point to the next node in the list because there is no "next node" beyond the last now. But addresses in memory are adjacent, aren't they? So last +1 should normally point to one Link-size address in memory next to the last, that is right after that. Isn't it?

    And what do you meaning by deleting a node for example in pop_back(), please?
    Do you mean I should necessarily use the keyword delete or if I make the node be out of the list would be acceptable?
    Last edited by tomy12; Yesterday at 01:40 AM.

  4. #19
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,632

    Re: A strange error with definition and declaration of a member function

    'One past the end' is a notional concept, not an actual physical one. In the STL if an iterator is at end() then you can't dereference that iterator as it doesn't actually point to 'proper allocated memory'. AFAIK (though some c++ language standard guru may know differently) how end() is implemented is down to the people doing the implementation and is not specified. All that is specified is the required behaviour - you can test against end(), if an iterator is one before end() then next() and ++ will give end() etc. If the container is empty then begin() will equal end() so that the code

    Code:
    for (auto i = cont.begin(); i != cont.end(); ++i)
    //process iterator
    will always work correctly as expected.

    For deleting a node, yes you need to use the keyword delete to delete the allocated memory for each of the nodes in the linked list. So you have to traverse the list and delete the node memory as in the your code in post #16.
    Last edited by 2kaud; Yesterday at 03:52 AM.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

  5. #20
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,632

    Re: A strange error with definition and declaration of a member function

    Created a copy constructor as follows and it works fine
    The 'interesting' thing about c++ is that you can have code that produces the expected result/display, works as expected in test situations, yet be totally wrong coded!
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)