Archived

This topic is now archived and is closed to further replies.

Acessor style

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

Hi, in a recent project I need an an object x of class A that holds a reference (pointer) to some object _y of class B (or possibly any of it''s subclasses), something like this: class A { private: B* _y; public: void set(B* y) { if(y==NULL) throw(1); _y=y; } B* get() { return(_y); } } x; A friend sugested me to use a diferent style: class A { private: B* _y; public: void set(B& y) { _y=&y; } B& get() { return(*_y); } } x; he said that this way I have an extra protection againt wild pointers, and also I can get some speed improvement because compilers should be able to perform some minor optimizations by using references instead of pointers. Everything seens right to me but it looks "unusual", so I''d hope somebody can point me any pitfalls or issues about this new style. thanks. PS: maybe you can recommend a tool for measuring speed of very small functions, I tryed using the c library clock() and the mingw profiler and it seens the loop a put around the functions takes a lot more time to execute than the functions itselfs.

Share this post


Link to post
Share on other sites
Nothing unusual - you cannot ever have a null reference. The few C++ constructs that might generate one throw an exception instead.

However, a safe implementation for get would be :
const B& get() const { return (*_y); }

If you make it non-const, users can modify the object pointed by _y without the containing object x being aware if it. Which is really no different from making the variable public, especially in the first version of your code : don''t fool yourself into thinking you are using "proper encapsulation techniques".

Additionally... don''t throw ints, derive a custom exception class from an existing one instead.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
Fruny, thanks for your reply, but this is just a "simple as possible" code to show a point. The real code have all the const''s inline''s and apropriate exception classes. I''m just worried about taking pointers out of references, any side effects that it may cause, or performance impacts.

Share this post


Link to post
Share on other sites
quote:
Original post by svpace
I'm just worried about taking pointers out of references, any side effects that it may cause, or performance impacts.


No side effect. Once translated into machine code, a pointer and a reference are exactly the same thing : a reference is an implicitely-dereferenced constant pointer whose semantics ensure is never 'null'.

Thus, taking the address of a reference is essentially a no-op.

The only way you could get one would be to dereference a null pointer ( int& i = *(int*)0; )... which has undefined behaviour.

In fact, compilers use these invariants for optimisation, so using references can potentially yield better performance, as they tell more precisely to the compiler 'what you mean' than pointers do.

A quick test shows the code generated is the same in both cases :

z = x.get();
mov eax, DWORD PTR _x
mov eax, DWORD PTR [eax]


Side note: the same argument can be addressed to all those people who would rather rebuild C++ features such as virtual functions from scratch rather than on relying on 'idioms' the compiler is aware of.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on March 2, 2003 2:52:03 AM]

Share this post


Link to post
Share on other sites