Jump to content
  • Advertisement
Sign in to follow this  
coordz

Pointer to member object operator

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

Currently I have a class like
class B;

class A {
public:
  B *bptr;
}
At certain times during my program bptr gets set to a new B. I then do things like B->myFunction(). Now I've implement the [] operator in B. All is okay upto here. Then I want to be able to do bptr....... but I don't think I can because bptr is a pointer to B not actually a B itself. I think I'd have to do bptr->??? Or something like that. How can I declare bptr so I can do things like bptr and it call my [] operator, which is what I want to do? TIA btw bptr used to be an array which is used extensively through my code as bptr[]. I want to replace the simple array with an object with the [] operator so I don't have to re-write my code.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by coordz
btw bptr used to be an array which is used extensively through my code as bptr[]. I want to replace the simple array with an object with the [] operator so I don't have to re-write my code.

C++ already has an object that behaves like an array, its called std::vector, it even overloads the [] operator and come with handy methods to determine the size of the array, whether its empty or not, to remove elements from anywhere in the array and all sorts really, so theres no need to write your own!
As with most things, its recommended to use the tools that come with the language.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
Quote:
Original post by coordz
btw bptr used to be an array which is used extensively through my code as bptr[]. I want to replace the simple array with an object with the [] operator so I don't have to re-write my code.

C++ already has an object that behaves like an array, its called std::vector, it even overloads the [] operator and come with handy methods to determine the size of the array, whether its empty or not, to remove elements from anywhere in the array and all sorts really, so theres no need to write your own!
As with most things, its recommended to use the tools that come with the language.

Thanks dmatter but sadly std::array doesn't cut it. I'm actually implementing a wrapper for a sparse array (based on std::map) which includes some additional functionality. I don't understand the STL well enough to start modifying std::map so I'm wrapping it.

Share this post


Link to post
Share on other sites
Depends on your intended usage. Your current approach is valid as long as:

  • B is a container class with a subscript operator defined (std::vector, std::map, std::deque or your own associative container).
  • An instance of class A may reference zero or one such containers, the reference must be re-seatable, the referenced container is not owned by the instance, and guaranteed to remain available for the lifetime of the instance.


As stevenmarky explained, the correct use case for this is (*this->bptr).

If, however, the referenced container is internal (as you seem to imply), then you can manipulate an instance instead of a pointer, either defining it as B b; and using it as this->b; instead (if you can equate the concepts of "no container" and "empty container") or defining it as boost::optional<B> b; and using it, again, as (*this->b);. As a last resort, you could use auto_ptr<B> b; to emulate the external behaviour of boost::optional, though you would need to write any copy constructors for A yourself.

Of course, other ownership conditions may call for boost::shared_ptr instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by coordz
I'm actually implementing a wrapper for a sparse array (based on std::map) which includes some additional functionality. I don't understand the STL well enough to start modifying std::map so I'm wrapping it.

This is fine. If you werent adding extra functionality then you might as well use a std::map directly, probably using a typedef to hide the tedious template syntax.
You won't ever want to modify the STL container directly, aggregating them in another class in this way is the correct way to extend them, along with using/writing STL compliant algorithms.
Modifying or inheriting from STL containers is a definate NO.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
Quote:
Original post by coordz
I'm actually implementing a wrapper for a sparse array (based on std::map) which includes some additional functionality. I don't understand the STL well enough to start modifying std::map so I'm wrapping it.

This is fine. If you werent adding extra functionality then you might as well use a std::map directly, probably using a typedef to hide the tedious template syntax.
You won't ever want to modify the STL container directly, aggregating them in another class in this way is the correct way to extend them, along with using/writing STL compliant algorithms.
Modifying or inheriting from STL containers is a definate NO.


What kind of "additional functionality", though?

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
What kind of "additional functionality", though?

Well to be honest I dont really know, off the top of my head I cant really think what you would want out of a one-dimensioned sparse array that you can't get from a vanilla std::map. Perhaps its as simple as implementing the adaptor pattern?

But in general, 'additional functionality' would just be anything that isnt provided by the std::map, whether that's in terms of the interface in the case of the adapter pattern or if you were adding some form 'higher level' functionality such as a multi-dimensional sparse array or building a resource manager perhaps.

Edit: I could possibly attempt to generalise this to "any class that provides a service whos implementation is based on an STL container should aggregate the container."

Share this post


Link to post
Share on other sites
Quote:
btw bptr used to be an array which is used extensively through my code as bptr[]. I want to replace the simple array with an object with the [] operator so I don't have to re-write my code.


When dealing with custom types and pointers, prefer to use typedefs. For example:

class B;

class A {
public:
typedef B * BPtr;

BPtr bptr;
};

...

A a;
A::BPtr p = a.bptr;

// or

class B;
typedef B * BPtr;

class A {
public:
BPtr bptr;
};

...

A a;
BPtr p = a.bptr;




But for your particular case:


class BPtr
{
public:
B &operator( size_t subscript )
{
return //get proper element from storage
}

// also override assignment operator, copy constructor, and everything else.

private:
// storage
}

class A {
public:

private:
BPtr bptr;
}


This should allow you to keep the same code elsewhere.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
Quote:
Original post by Zahlman
What kind of "additional functionality", though?

Well to be honest I dont really know, off the top of my head I cant really think what you would want out of a one-dimensioned sparse array that you can't get from a vanilla std::map. Perhaps its as simple as implementing the adaptor pattern?

But in general, 'additional functionality' would just be anything that isnt provided by the std::map, whether that's in terms of the interface in the case of the adapter pattern or if you were adding some form 'higher level' functionality such as a multi-dimensional sparse array or building a resource manager perhaps.

Edit: I could possibly attempt to generalise this to "any class that provides a service whos implementation is based on an STL container should aggregate the container."


Hehe. I'll wait for the OP's answer ;) But what I'm getting at is that this functionality might be better implemented at the containing-class level instead.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!