Boost logo

Boost Users :

From: Ovanes Markarian (om_boost_at_[hidden])
Date: 2008-03-28 06:05:02


Hello Daniel,

I thought about such a class as well. The main disadvantage of it is that it
is impossible to use with standard containers. :(
Standard containers (e.g. std::vector) pre-allocate space for some number of
instances and use the placement new operator to place items in the
pre-allocated memory and when deriving form
nondynamic makes it impossible.

With kind regards,
Ovanes

On Fri, Mar 28, 2008 at 10:40 AM, Daniel Lidström <daniel.lidstrom_at_[hidden]>
wrote:

> Hi there!
>
> (I recently posted a similar message to microsoft.public.vc.language,
> but the response was so bad I thought I would post here instead.)
>
> I have created a utility class that I think is useful, called nondynamic.
> The purpose is sort of like boost::noncopyable, but I disallow any
> dynamic/
> pointer usages. For example, & and -> are disabled. Operator new/delete as
> well.
> Let me show nondynamic:
>
> // all members are private
> class nondynamic
> {
> // disallow operator new
> static void* operator new(std::size_t);
> static void* operator new(std::size_t, const std::nothrow_t&) throw();
> static void* operator new[](std::size_t);
> static void* operator new[](std::size_t, const std::nothrow_t&) throw();
>
> // disallow operator delete
> static void operator delete(void*){}
> static void operator delete(void*, const std::nothrow_t&) throw(){}
> static void operator delete[](void*){}
> static void operator delete[](void*, const std::nothrow_t&) throw(){}
>
> // disallow address-of
> const nondynamic* operator&() const;
> /* */ nondynamic* operator&() /* */;
>
> // disallow ->
> const nondynamic* operator->() const;
> /* */ nondynamic* operator->() /* */;
> };
>
> Using this class is as simple as using boost::noncopyable:
>
> struct DataIO : private nondynamic
> { ... };
>
> Now you are only able to use DataIO as a value type. All other usages are
> disabled. I think this promotes safe programming, in that pointer usage
> is minimized (it seems with pointers, new/delete/null is never far away).
>
> Let me illustrate how this class can be used most effectively. I thought
> it would be nice to use nondynamic when you have a class hierarchy, and
> a factory method.
>
> Here's the base class:
>
> struct IDataIO
> {
> virtual void Write(const std::string& str) = 0;
> virtual void Read(char* buffer, std::size_t size) = 0;
> };
> typedef boost::shared_ptr<IDataIO> IDataIOPtr;
>
> A sample subclass:
>
> struct SerialDataIO : IDataIO
> {
> void Write(const std::string&) { std::cout << __FUNCTION__ << std::endl;
> }
> void Read(char*, std::size_t) { std::cout << __FUNCTION__ << std::endl;
> }
> };
>
> Here's the wrapper class that inherits from nondynamic:
>
> struct DataIO : IDataIO, private nondynamic
> {
> DataIO(IDataIOPtr dataIO) : mDataIO(dataIO) {}
>
> void Write(const std::string& str) { mDataIO->Write(str); }
> void Read(char* buffer, std::size_t size) { mDataIO->Read(buffer, size);
> }
>
> private:
>
> IDataIOPtr mDataIO;
> };
>
> And finally, the factory:
> DataIO CreateDataIO(int i)
> {
> if( i==0 )
> return IDataIOPtr(new SerialDataIO);
> else
> throw std::runtime_error("Could not create DataIO");
> }
>
> Now the clients of the class hierarchy uses the wrapper, and are
> completely
> isolated from pointers:
>
> DataIO dataIO = CreateDataIO(0);
> dataIO.Write("Hello");
> char buffer[1024];
> dataIO.Read(buffer, sizeof(buffer));
>
> It should be impossible to misuse DataIO.
> What do you think about nondynamic? Is it implemented correctly?
> Named appropriately? Useful at all? Any comments gladly accepted :-)
>
> Thanks in advance!
>
> --
> Daniel
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net