Re: Is UniversalPointer a good idea?
Am Sonntag, 25. Januar 2015 15:00:16 UTC+1 schrieb DeMarcus:
I want to be able to receive a polymorphic object to a class. However, I
want this class to be able to receive all kinds of pointers there are in
C++. Since this class is going to be an interface, I don't really want
to have one method for each pointer type since that would be too tedious
for the users of the interface.
I came up with the following idea of a UniversalPointer to take care of
all kinds of circumstances.
[...snip...]
#include <iostream>
#include <memory>
template<class T>
class UniversalPointer
{
public:
UniversalPointer( T* pointer )
: universalPointer_( pointer ) {}
UniversalPointer( T& reference )
: universalPointer_( &reference ) {}
UniversalPointer( T&& reference )
: universalPointer_( &reference ) {}
UniversalPointer( const std::unique_ptr<T>& uPointer )
: universalPointer_( uPointer.get() ) {}
UniversalPointer( const std::shared_ptr<T>& sPointer )
: universalPointer_( sPointer.get() ) {}
[...snip...]
private:
T* universalPointer_;
};
I can't imagine a situation in which I would use something like this.
[...snip...]
int fnc( UniversalPointer<Number> upn )
{
upn->increase();
return upn->getNumber();
}
int main()
{
Number number( 0 );
std::unique_ptr<Number> uptrNumber( new Number( 42 ) );
std::cout << fnc( &number ) << std::endl;
std::cout << fnc( number ) << std::endl;
std::cout << fnc( std::move( number ) ) << std::endl;
std::cout << fnc( Number( 4710 ) ) << std::endl;
std::cout << fnc( uptrNumber ) << std::endl;
std::cout <<
fnc( std::shared_ptr<Number>( std::move( uptrNumber ) ) )
<< std::endl;
Wny not simply write this?
int fnc( Number & u )
{
n.increase();
return n.getNumber();
}
Surely you can dereference a pointer at the call site manually to
invoke it.
And what is the purpose of doing the following?
std::cout << fnc( std::move( number ) ) << std::endl;
std::cout << fnc( Number( 4710 ) ) << std::endl;
Do you really want `fnc` to take and mutate *both* lvalues as well as
rvalues? Usually, you want just one kind of non-const reference where
allowing the other kind would actually be an error (in most cases).
Only rarely, I found myself adding an overload like this:
int fnc( Number && n ) { return fnc(n); }
when I really wanted to deal with both kinds of values. But this
really is an exception and I don't think it justifies creating an
extra pointer wrapper that can be initialized with both lvalues and
rvalues.
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]