Jump to content
  • Advertisement
Sign in to follow this  
thedevdan

Member-access operator insanity

This topic is 5413 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(For your information, I have VC2003.NET) I've just rolled and tested my own smart pointer, and it was working perfectly under all tests until I tested it inside of a std::vector. This is when it starts getting weird. From what I know, operator -> keeps applying itself to the returned result until the return result has no operator ->, and it evaluates to that result. Here's what's happenning.
  • The operator -> applied to an iterator stops applying itself when it gets to my smart pointer. So I have to dereference the vector and then call operator ->.
  • After doing that, I get an access violation inside of my operator ->. That didn't make sense to me, because it was working fine before. So, I put a break-point in the code, ran it in debugger, and put the pointer in the 'watch' list. From inside of the member function, the symbol isn't found! At any other point in the code, if I call operator ->, the symbol *is* found, but if I call it from a dereferenced iterator, it isn't! Why would that be happenening? It makes absolutely no sense, and I'll bet it's connected to why I'm getting an access violation.
Here is my code:
template <class Type>
class ValuePointer
{
public:
	ValuePointer() : value_(0)
	{
	}

	ValuePointer(const ValuePointer<Type>& original)
	{
		if (original.value_)
		{
			value_ = new Type(*original.value_);
		}
		else
		{
			value_ = 0;
		}
	}

	ValuePointer(Type* value)
	{
		if (value)
		{
			value_ = new Type(*value);
		}
		else
		{
			value_ = 0;
		}
	}

	ValuePointer<Type>& operator =(const ValuePointer<Type>& original)
	{
		if (original.value_)
		{
			if (value_)
			{
				*value_ = *original.value_;
			}
			else
			{
				value_ = new Type(*original.value_);
			}
		}
		else
		{
			delete value_;
			value_ = 0;
		}
		return *this;
	}

	ValuePointer<Type>& operator =(Type* value)
	{
		if (value)
		{
			if (value_)
			{
				*value_ = *value;
			}
			else
			{
				value_ = new Type(*value);
			}
		}
		else
		{
			delete value_;
			value_ = 0;
		}
		return *this;
	}

	Type& operator *()
	{
		return *value_;
	}

	Type* operator ->()
	{
		return value_; //Break point is here
	}
	
	bool null()
	{
		return !value_;
	}

private:
	Type* value_;
};







Share this post


Link to post
Share on other sites
Advertisement
Quote:
This is when it starts getting weird. From what I know, operator -> keeps applying itself to the returned result until the return result has no operator ->, and it evaluates to that result. Here's what's happenning.


Incorrect, operator-> re-applies itself until the returned value is a pointer.

Quote:
and I'll bet it's connected to why I'm getting an access violation.


You gave the code for your class. Fine. Give a complete snippet of code that triggers that access violation - so that I can compile and test it.

Share this post


Link to post
Share on other sites
Oh sorry about that.

#include <vector>
#include <iostream>

template <class Type>
class ValuePointer
{
public:
ValuePointer() : value_(0)
{
}

ValuePointer(const ValuePointer<Type>& original)
{
if (original.value_)
{
value_ = new Type(*original.value_);
}
else
{
value_ = 0;
}
}

ValuePointer(Type* value)
{
if (value)
{
value_ = new Type(*value);
}
else
{
value_ = 0;
}
}

ValuePointer<Type>& operator =(const ValuePointer<Type>& original)
{
if (original.value_)
{
if (value_)
{
*value_ = *original.value_;
}
else
{
value_ = new Type(*original.value_);
}
}
else
{
delete value_;
value_ = 0;
}
return *this;
}

ValuePointer<Type>& operator =(Type* value)
{
if (value)
{
if (value_)
{
*value_ = *value;
}
else
{
value_ = new Type(*value);
}
}
else
{
delete value_;
value_ = 0;
}
return *this;
}

Type& operator *()
{
return *value_;
}

Type* operator ->()
{
return value_;
}

bool null()
{
return !value_;
}

private:
Type* value_;
};
////
class Talker
{
public:
void Talk()
{
std::cout << "bla bla bla\n";
}
};
///
int main()
{
ValuePointer<Talker> t1 = new Talker;
ValuePointer<Talker> t2 = new Talker;
ValuePointer<Talker> t3 = new Talker;
ValuePointer<Talker> t4 = new Talker;

std::vector<ValuePointer<Talker> > v;

v.push_back(t1);
v.push_back(t2);
v.push_back(t3);
v.push_back(t4);

for (std::vector<ValuePointer<Talker> >::iterator t; t != v.end(); ++t)
{
(*t)->Talk(); //Violation is here. Notice how I have to dereference the iterator.
}

return 0;
}




Compile-ready.

EDIT: Could someone move this into General Programming? It's here by accident. Thank you.

Share this post


Link to post
Share on other sites
You forgot to initialize the iterator t.
Adding t = v.begin() to the loop fixes that.

You have to add the dereference because std::vector<T>::iterator::operator->() does return a pointer to T, stopping the chain.

Thread moved as requested.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
You forgot to initialize the iterator t.
Adding t = v.begin() to the loop fixes that.

You have to add the dereference because std::vector<T>::iterator::operator->() does return a pointer to T, stopping the chain.

Thread moved as requested.


Thank you so much, that did the trick! And I now understand why I have to dereference.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!