class API return a const&, optional, shared_ptr

hello,
I have a class A that holds a container of objects of type B indexed by int
for e.g.
Typically, I have a function of A
class A {
public:
const B& getB(int <index> ) const;
private:
std::map< int, shared_ptr<B> > listOfBs_;
};
The implementation of getB could be
const B& A::getB(int <index> ) const
{
//what to do if index not found
}
A number of solutions I think of:
1.
boost::optional

I prefer the static class member option. Note that it is *not* necessary for clients to have access to that static if the type has a well defined invalid value. This is true for shared_ptr. If the static member is null, then clients need merely check the returned pointer in the normal fashion, as they should any returned pointer. On the other hand, one might ask why you would want to return a const ref to a shared_ptr. That one can cheaply return copies is one of the big features of shared_ptr. At 07:15 AM 11/25/2008, Hicham Mouline wrote:
hello,
I have a class A that holds a container of objects of type B indexed by int for e.g.
Typically, I have a function of A
class A { public: const B& getB(int <index> ) const; private: std::map< int, shared_ptr<B> > listOfBs_; };

I have realized I have an extra requirement: class A and C derive from Base (// cannot be instantiated, it has pure virtuals) class Aelem and Celem derive from BaseElem (// cannot be instantiated, it has pure virtuals) class Base { // cannot be instantiated ... virtual const BaseElem& get() const =0; }; Class A : Base { ... const Aelem & get() const; private: map< int, shared_ptr< Aelem > > map_Aelem_s_; }; Class C : Base { ... const Celem & get() const; private: map< int, shared_ptr< Celem > > mapof Celem s_; }; Class Aelem { ... const static Aelem notFound; }; // even if f() below is supposed to use the above classes polymorphically, // it would be useful to declare A and C's get() to return Aelem and Celem directly Void f( const Base& b ) { const BaseElem & bref = b.get(); // here I can't test that bref is "NotFound" coz I can't instantiate a NotFound BaseElem object (BaseElem is not instantiable) I can't say that Base::get() returns a shared_ptr< const BaseEleme > because then what about A.get() and D.get(), if they return shared_ptr< const Aelem > and shared_ptr< const DElem > the virtual function will not be overriden Same problem with boost::optional<BaseElem> vs boost::optional<AElem> boost::optional<CElem> raw pointers seem to be the way to go, -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Alan M. Carroll Sent: 25 November 2008 13:08 To: boost-users@lists.boost.org Subject: Re: [Boost-users] class API return a const&, optional, shared_ptr I prefer the static class member option. Note that it is *not* necessary for clients to have access to that static if the type has a well defined invalid value. This is true for shared_ptr. If the static member is null, then clients need merely check the returned pointer in the normal fashion, as they should any returned pointer. On the other hand, one might ask why you would want to return a const ref to a shared_ptr. That one can cheaply return copies is one of the big features of shared_ptr. At 07:15 AM 11/25/2008, Hicham Mouline wrote:
hello,
I have a class A that holds a container of objects of type B indexed by int for e.g.
Typically, I have a function of A
class A { public: const B& getB(int <index> ) const; private: std::map< int, shared_ptr<B> > listOfBs_; };

// even if f() below is supposed to use the above classes
polymorphically, >// it would be useful to declare A and C's get() to return Aelem and Celem >directly You'd have to have two get functions (get and get2?), the inherited for polymorphism and another where you know the type you're dealing with.
const B& A::getB(int <index> ) const { //what to do if index not found }
I assume you have good reason for not throwing an error or using a get function that returns an error code Could a redesign simplify things? ****************************************************************************** "This message and any attachments are solely for the intended recipient and may contain confidential and privileged information. If you are not the intended recipient, any disclosure, copying, use, or distribution of the information included in this message and any attachments is prohibited. If you have received this communication in error, please notify us by reply e-mail and immediately and permanently delete this message and any attachments. Thank you." Interactive Transaction Solutions Ltd (2473364 England) Registered Office: Systems House, Station Approach Emsworth PO10 7PW ********************************************************************** Ce message �lectronique contient des informations confidentielles � l'usage unique des destinataires indiqu�s, personnes physiques ou morales. Si vous n'�tes pas le destinataire voulu, toute divulgation, copie, ou diffusion ou toute autre utilisation de ces informations, est interdite. Si vous avez re�u ce message �lectronique par erreur, nous vous remercions d'en avertir son exp�diteur imm�diatement par email et de d�truire ce message ainsi que les �l�ments attach�s. Interactive transaction Solutions SAS- France (RCS Pontoise : 489 397 877) Si�ge social : Parc Saint Christophe, 10, Avenue de l�Entreprise 95865 Cergy-Pontoise Cedex ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________

Hicham Mouline wrote:
hello,
I have a class A that holds a container of objects of type B indexed by int for e.g.
Typically, I have a function of A
class A { public: const B& getB(int <index> ) const; private: std::map< int, shared_ptr<B> > listOfBs_; };
The implementation of getB could be
const B& A::getB(int <index> ) const { //what to do if index not found }
A number of solutions I think of:
1. boost::optional
getB(int <index> ) const { } 2. change signature to const B* getB(int <index> ) const
3. Define a static const B notFoundB; const B& A::getB(int <index> ) const returns notFoundB when not found and have API users compare return value with notFoundB
I suppose the cheapest in overhead/performance is 2... optional must have some time overhead?
Are there advised solutions? Favourites in terms of style?
Regards,
There's always:
boost::shared_ptr<const B> get(int i) const
{
... // find iterator at key i
return (... != listOfBs.end())
? const_pointer_cast<const B>(*non_end_itr)
: boost::shared_ptr<const B>();
}
or better yet, you can fully encapsulate the internals of A, while
simplifying the class interface:
void A::visit(int i, boost::function
participants (4)
-
Alan M. Carroll
-
Hicham Mouline
-
Jeff Flinn
-
Patrick Loney