Jump to content
  • Advertisement
Sign in to follow this  
sipickles

Overloading operator - in C++

This topic is 4250 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

Hello, After seeing it done in Boost::smart_ptr, I decided it would be helpful to overload the -> operator in a few of my classes. For example, my CEffect class is a wrapper for ID3DXEffect interface. At present, I have been having to use the effect like this:
LPD3DXEFFECT CEffect::GetEffect( void )
{
	return  m_effect;
}

/////////////////////////////////////////////////

m_effect->GetEffect()->SetMatrix("World", &temp );

I hoped I could do this too:
LPD3DXEFFECT CEffect::operator->( void )
{
	return  m_effect;
}

/////////////////////////////////////////////////

m_effect->SetMatrix("World", &temp );

... but it doesn't seem to work. I am sure I am doing something simple wrong. Any advice gratefully received. Simon

Share this post


Link to post
Share on other sites
Advertisement
Hmm, I don't know. It just doesn't seem like such a great idea. In the case of Boost's smart pointers, it's still intuitive. But in this case it would be very confusing to overload that operator.
Anyhow it seems like you need to return a pointer (or some other class overriding the -> operator), so that the -> is a valid operation on the return type.

Share this post


Link to post
Share on other sites
m_effect is a pointer, so you need to dereference the pointer to call CEffect::operator->(), which you overloaded:

(*m_effect)->...

Share this post


Link to post
Share on other sites
Hmm, no, thats not quite it.

The overloading compiles fine.

When using the effect, Thats where it complains. Here's it written another way:


class CEffect
{
CEffect( char* filename ) { m_fx = NULL ; D3DXCreateEffectFromFile( filename, m_fx, .....etc); }
~CEffect() { SAFE_RELEASE( m_fx ); }

ID3DXEffect* m_fx;

public:

ID3DXEffect* operator->() { return m_fx; }

//..... other functionality
}

CEffect* m_effect = new CEffect("fire.fx");

m_effect->SetMatrix("World", worldMatrix);

///////////////////////////////////////
// Output
error C2039: 'SetMatrix' : is not a member of 'CEffect'







Does that make it any clearer?

Thanks

Simon

Share this post


Link to post
Share on other sites
Boost smart pointers are actual instances of objects, not pointers. Your m_effect variable in your last example is a raw pointer to a CEffect instance. Which means that the -> operator applies to the raw pointer.

Now if you had done this:
class CEffect
{
CEffect( char* filename ) { m_fx = NULL ; D3DXCreateEffectFromFile( filename, m_fx, .....etc); }
~CEffect() { SAFE_RELEASE( m_fx ); }

ID3DXEffect* m_fx;

public:

ID3DXEffect* operator->() { return m_fx; }

//..... other functionality
}

//An actual instance, not a pointer
CEffect m_effect("fire.fx");

m_effect->SetMatrix("World", worldMatrix);
then that last part should work. Do you see the difference? The operator must apply to an actual instance, not to a raw pointer to an instance.

Share this post


Link to post
Share on other sites
I just did a quick test:


class MyClass
{
public:
int myInt;
};

class TestClass
{
public:
TestClass(void);
~TestClass(void);

void setInt(int newInt)
{
myObject.myInt = newInt;
};

MyClass* TestClass::operator->( void )
{
return (&myObject);
};

private:
MyClass myObject;

};






TestClass tc;
tc.setInt(20);
std::cout << tc->myInt;




Compiles and prints out 20 as expected.

EDIT: Agony most likely hit the nail on it's head.

Share this post


Link to post
Share on other sites
Of course they are. I'd forgotten that.

Unfortunately, ID3DXEffect is an abstract class. It has to be a pointer :(

Guess I'll have to go back to my old way!

Share this post


Link to post
Share on other sites
Does CEffect inherit from ID3DXEffect? Or is CEffect just a wrapper around an ID3DXEffect pointer? If it is the latter, then all you need is an instance of CEffect. It doesn't matter that your wrapped effect is a pointer. -> returns a pointer anyway, so that's fine.

Share this post


Link to post
Share on other sites
Quote:
Original post by sipickles
Of course they are. I'd forgotten that.

Unfortunately, ID3DXEffect is an abstract class. It has to be a pointer :(

Guess I'll have to go back to my old way!


As Agony pointed out it's the object of type CEffect which mustn't be a pointer, since if it's a pointer then the -> operator would that of a pointer and not that of an object of type CEffect. The returned value of the operator -> should be a pointer, which it is, so you don't have a problem there.

Share this post


Link to post
Share on other sites
I only skimmed the thread, so this may be completely irrelevant, but...

If the only purpose of the wrapper is to provide support for RAII, you might consider instead using boost::shared_ptr along with a custom deleter. You would then get operator->() (along with a number of other useful features and behaviors) essentially for free.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!