Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi every one

I'm trying to overload the assignment operator in this class:
C++
template<class _T>
class tree
{
public:
    tree();

    class pre_iterator
    {
        // I just add the below constructor. The others two already existed.
        pre_iterator(node& __node);
        pre_iterator(node* __node);
        pre_iterator(node* __node, node* __root);
        // Operators
        pre_iterator& operator=(const pre_iterator& __other);
        bool operator==(const pre_iterator& __other);
    };

    pre_iterator end();
};

template<class _T>
typename tree<_T>::pre_iterator& tree<_T>::pre_iterator::operator=(const typename tree<_T>::pre_iterator& __other)
{
	// Missing code here but is not important.
	return (*this);
}

// Equal.
template<class _T>
typename bool tree<_T>::pre_iterator::operator==(const typename tree<_T>::pre_iterator& __other)
{
	return (this->_M_node == __other._M_node);
}

// Iterator end of the tree - null node.
template<class _T>
typename tree<_T>::pre_iterator tree<_T>::end()
{
	assert(_M_root != NULL);
	return (pre_iterator(NULL));
}


And in main function I have this:

C++
tree<A>::pre_iterator it = my_tree->end();
it == my_tree->end();


What happens here is that the comparison (equal and not equal operator too) is called but the assignment not.
I cannot figure out what is missing, if this is possible to do what I'm trying to do.

Best regards and thanks in advance
Filipe Marques
Posted
Updated 19-Mar-13 13:33pm
v2

When you overload the assgnment operator you should also create a copy constructor.

You are creating a new instance of tree<A>::pre_iterator ...

Given:
class A
{
    
public:
    A()
    {
        std::printf("In constructor\n");
    }

    A(const A& other)
    {
        std::printf("In copy constructor\n");
    }

    A(A&& other)
    {
        std::printf("In move constructor\n");
    }


    A& operator = (const A& other)
    {
        std::printf("In copy assignment operator\n");
        return *this;
    }

    A& operator = (A&& other)
    {
        std::printf("In move assignment operator\n");
        return *this;
    }
};

A a;

int _tmain(int argc, _TCHAR* argv[])
{
    A b = a;
    return 0;
}


You get the output:
In constructor
In copy constructor



Best regards
Espen Harlinn
 
Share this answer
 
v2
Comments
Filipe Marques 19-Mar-13 19:39pm    
Thanks for your reply. As I said to Steve, the copy constructor is not being called. I don't get it. I think I need a good night of sleep. :)
Stefan_Lang 20-Mar-13 6:02am    
Check out the following link to get a better understanding of your misunderstanding:

http://www.gotw.ca/gotw/001.htm

It explains the different ways of initializing a variable, and why in your case you are calling a constructor, not an operator.

Also, judging by your comments, you may have misunderstood the term copy constructor: see the code example Steve44 supplied in his solution (I'm looking at V4).
Stefan_Lang 20-Mar-13 6:04am    
Sorry Espen, looks like accidentally posted my previous response as a comment to your solution - it was meant as a response to Filipes comment.
Espen Harlinn 20-Mar-13 7:53am    
It was kind of baffling ...
Filipe Marques 20-Mar-13 17:38pm    
Thanks for your answers. Please, read the comment that I did in Steve solution, for I do not a copy-paste of it. (:
The line you are writing

C++
tree<a>::pre_iterator it = my_tree->end();

looks like an assignment, but it will execute a copy constructor. Try to implement a copy constructor for the pre_iterator class and you will see that it is executed.

The copy constructor you should implement is like this:

C++
class pre_iterator
{
    // I just add the copy constructor. Keep the others as required
    pre_iterator(const pre_iterator& __original)
    {
        // implement the copy operation here,
        // same as in the assignment operator.
    }


As templates are not supporting the concept of a user-implemented copy-constructor (they always execute the default copy-constructor), but every constructor (even if it looks like a copy-constructor) is just a constructor, you have to force the match to resolve to your constructor:

C++
tree<A>::pre_iterator it = (const tree<A>::pre_iterator)my_tree->end();

Just tried this and it executed the "copy"-constructor above.
 
Share this answer
 
v6
Comments
Filipe Marques 19-Mar-13 19:35pm    
Hi thanks for your answer. I updated the code with the constructors. I put printf's all of them and only the second is call (from tree<_T>::pre_iterator tree<_T>::end() method). I think there is something missing...a really basic thing :)
Steve44 19-Mar-13 20:12pm    
Hi Filipe,
the constructors you define above are constructors, but none is a copy constructor. I add the code to my solution above.
Eugen Podsypalnikov 20-Mar-13 3:13am    
// implement the copy operation here,
// same as in the assignment operator.
pre_iterator(const pre_iterator& __original)
{
*this = __original; // ;)
}
Steve44 20-Mar-13 4:20am    
Hi Eugen,
Not necessarily correct. If you have a shallow object, this might work. If you have allocated resources the assignment operator should free the previous values and then allocate new ones for the copy, the copy constructor however will not have any previously allocated resources and might not even be fully initialized.
Eugen Podsypalnikov 20-Mar-13 7:59am    
You are right ! The init part (list) must be injected firstly, if necessary :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900