473,698 Members | 2,883 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Design Woes.....


I was relieved somewhat when I saw a post by Andrei Alexandrescu
highlighting an similar issue I'm faced with:
So here's what Andrei Alexandrescu wrote:
[start]
I code a generic object factory. Obviously, the factory has a member
function like CreateObject that returns a newly allocated object.

The problem is, I break an important coding standard: never return
pointers to newly allocated memory. Never pass ownership by returning
pointers. Never do what strdup does. And never means never.
[/stop]

I suspect I should be concerned about breaking the coding standards but
I haven't got that far yet. For simplicity, I'll highlight the stuff -
per the source below - that counts. So now consider:

#ifndef FACTORY_H
#define FACTORY_H
# include <map>
# include <string>

struct stream;
class source //
{
public:
virtual bool load_from_strea m(stream& ds) = 0;
virtual void execute() = 0;
};
//////////////////////////////*//////
// factory
class ClassFactory
{
public:
virtual source* create()=0;
virtual std::string name()=0;
};

template < class T >
class FactoryWrapper
: public ClassFactory {
public:
virtual source* create(){
return T::create();
}
virtual std::string name(){
return T::name();
}
};

class Factories
{
std::map<std::s tring, ClassFactory*> _facts;
public:
void registerFactory ( ClassFactory* factory);
source* create(const stream& ds);
};

#endif;

struct test
: public source
{
static std::string name() {
return "test";
}
static test* create(){ return new test();}
};

// now we're ready. main.cpp
class testFact {
FactoryWrapper< test> class1Factory;
Factories factories;

// test m_test; // would like to copy ptest to an m_test or ..
public:
testFact () {
factories.regis terFactory(&cla *ss1Factory);
}

void record()
{
// use ptest or some variant
//ptest
}

void get_data()
{
char buffer[4096] = { "testing" };
size_t len = sizeof buffer / sizeof *buffer;
data_stream st (buffer, len);
if (st)
{
test *ptest =
static_cast<tes t*>(factories.c *reate(st));
if ( !ptest ) {
// do somethign with ptest
delete ptest;
}
}
}
};

Each call to create within get_data results in a call to memory that
must be freed. Trouble is: I need to use the ptest object elsewhere.
For instance within the record member function. That said, how does one
go about creating a local copy of the object for use elsewhere?

If I copy ptest to another object of type test, that's unsafe since the
memory will be freed by ptest.

Having said that. In an attempt to 'meet' coding standards, I suspect
I could pass a test object to the create function. I'm not so sure I
understand what this solves or I'm fully understanding how to achieve
this.

Thanks in advance.

Jul 23 '05 #1
10 1376
ma740988 wrote:
The problem is, I break an important coding standard: never return
pointers to newly allocated memory. Never pass ownership by returning
pointers. Never do what strdup does. And never means never.
There's a more encompassing guideline: Each time you code 'new', immediately
account for the 'delete'.

That affects your behavior as a programmer. When you type this, type that
too, very soon. And it leads to the rule you cite, if the client of that
interface might not be written yet, so you can't account for the delete.
class ClassFactory
{
public:
virtual source* create()=0;
Can you return std::auto_ptr<> ? I thought they could automatically up and
down cast themselves into derived types of 'source'.
struct test: public source
Could we see a real test case here, like from CPPUnit? ;-)
static test* create(){ return new test();}


Right. Now can't this return an auto_ptr too, of a type covariant with the
base class's type?

Also look at the Boost shared_ptr.

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand
Jul 23 '05 #2
| Right. Now can't this return an auto_ptr too, of a type covariant
with the base class's type?

Thus far it sounds like I'll need:
virtual std::auto_ptr<s ource*> create()=0;

I realize the auto_ptr approach has the built in semantics to do
automatic cleanup. From the sound of it I'll review the two approaches
you highlighted.
but here's the more important question. The returned object needs to
be available for use elsewhere. How do you approach this? Again.
Withiin the get_data member function, a ptest object is created. I'd
like to keep a local copy for use in multiple places - for instance the
record function illustrated above.

Jul 23 '05 #3


ma******@pegasu s.cc.ucf.edu wrote:
| Right. Now can't this return an auto_ptr too, of a type covariant
with the base class's type?

Thus far it sounds like I'll need:
virtual std::auto_ptr<s ource*> create()=0;
I think it's just 'std::auto_ptr< source>' which gives you a managed
pointer to a 'source' object. You can use the auto_ptr object as a
pointer, or you can get or release the pointed-to object (the 'source')
from it.
I realize the auto_ptr approach has the built in semantics to do
automatic cleanup. From the sound of it I'll review the two approaches
you highlighted.
but here's the more important question. The returned object needs to
be available for use elsewhere. How do you approach this? Again.
Withiin the get_data member function, a ptest object is created. I'd
like to keep a local copy for use in multiple places - for instance the
record function illustrated above.


Since the 'testFact' class does not maintain a pointer to memory
allocated by 'get_data', you have to pass a parameter to 'record' in
any event. In this case, you can pass a modifiable reference to
'std::auto_ptr< source>'. Thus, 'record' is able to own the object or
not (since the parameter is modifiable).

However, if you are going to keep a local copy of the memory allocated
by 'get_data', the whole auto_ptr argument becomes moot because your
'testFact' object can manage its own memory.

Incidentally, it is a good idea for a factory (protocol) to also
provide 'deallocate' and 'deleteObject' methods. This way, factory
implementations are free to allocate memory from places other than the
heap (for example, from pools or buffers). However, you can no longer
use 'auto_ptr' because you cannot associate a factory with it; it only
knows about new/delete. That is another problem for another day...

/david

Jul 23 '05 #4

| think it's just 'std::auto_ptr< source>' which gives you a managed
| pointer to a 'source' object. You can use the auto_ptr object as a
| pointer, or you can get or release the pointed-to object (the
'source')
| from it.

Even with auto_ptr, each call to get_data() will still require a
delete/freeing of the source object. Correct? Since the source object
is allocating memory on each call to create I'll need to release the
memory. I'm not sure what auto_ptr is buying me but I'll need to
research more.
| However, if you are going to keep a local copy of the memory
allocated
| by 'get_data', the whole auto_ptr argument becomes moot because your
| 'testFact' object can manage its own memory.

Agreed

| Incidentally, it is a good idea for a factory (protocol) to also
| provide 'deallocate' and 'deleteObject' methods.

Agreed. Ideally, I'd like for the 'factory' to delete the allocated
memory _ONLY_ after I get a copy for use in testFact. So now I need
to figure out a way to do::

class testFact {
test m_test;
public:

void get_data()
{
factories.c**re ate(st, &m_test); // pass in m_test object.
Have factory create test object and assign to m_test.
// Factory should
also delete test object
}

// use m_test in all the member functions that need it.
void record()
{
if (m_test.whateve r == 5) {}
}
};

How would you do this?

Jul 23 '05 #5

I have one more question: Before I had,

test *ptest =
static_cast<tes t*>(factories.c **reate(st));
if (ptest)
Now I'm made all the auto_ptr mods and I'm trying to do:

std::auto_ptr<r ecorder_to_gui> prec_to_gui =
(static_cast<st d::auto_ptr<rec order_to_gui>
(factories.cre ate(st)));

: error C2440: 'initializing' : cannot convert from 'source *' to 'test
*'

reinterpret_cas t (dont think dynamic_cast applied, nonetheless tried it
too to no avail) doesn't work here either so .....

Jul 23 '05 #6
You would do this using a shared pointer. Shared pointers are
reference-counted, so when the last existing shared pointer object is
destroyed, the memory contained in the shared pointer (i.e., that which
is allocated in 'get_data' by your factory) is returned to the
allocator (or factory, whic is in this case the new/delete
"allocator" ). /david

Jul 23 '05 #7
da********@warp mail.net wrote:
You would do this using a shared pointer. Shared pointers are
reference-counted, so when the last existing shared pointer object is
destroyed, the memory contained in the shared pointer (i.e., that which
is allocated in 'get_data' by your factory) is returned to the
allocator (or factory, whic is in this case the new/delete
"allocator" ). /david


What's a shared pointer?

Kristo

Jul 23 '05 #8
Kristo wrote:

da********@warp mail.net wrote:
You would do this using a shared pointer. Shared pointers are
reference-counted, so when the last existing shared pointer object is
destroyed, the memory contained in the shared pointer (i.e., that which
is allocated in 'get_data' by your factory) is returned to the
allocator (or factory, whic is in this case the new/delete
"allocator" ). /david


What's a shared pointer?


You allocate memory.
You hand out multiple pointers to that memory
All those pointers know how many of them exist. They
'share' the memory resource such that the last of them
that gets destroyed also deletes the memory.

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 23 '05 #9
Kristo wrote:
da********@warp mail.net wrote:
You would do this using a shared pointer. Shared pointers are
reference-counted, so when the last existing shared pointer object is
destroyed, the memory contained in the shared pointer (i.e., that which
is allocated in 'get_data' by your factory) is returned to the
allocator (or factory, whic is in this case the new/delete
"allocator" ). /david

What's a shared pointer?

Kristo


As mentioned by Philip earlier in the thread, take a look at the Boost
shared_ptr (http://www.boost.org/libs/smart_ptr/smart_ptr.htm) for an
implementation that has seen a good bit of real world use.

-Alan
Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
1717
by: Mark | last post by:
O, woe is me, to have seen what I have seen, see what I see! (That's Shakespeare for those who were wondering what I'm on about) I am "having fun" with cookies. And I wonder if I have missed something obvious.
0
1525
by: Cedric | last post by:
This is a 3 weeks old problem, but having found a solution (and having looked for one here, finding only this message), I'm replying now. From: Jive (someone@microsoft.com) Subject: Upgrade woes: Numeric, gnuplot, and Python 2.4 Date: 2004-12-11 18:45:10 PST > Here's my sitch: > > I use gnuplot.py at work, platform Win32. > I want to upgrade to Python 2.4.
3
3452
by: Angel Cat | last post by:
Trying to get my jobs to send mail when job fails. Should be easy but it's giving me headache Had a whole slew of issues. Outlook is installed with a n outlook mail profile set up that can send mail in outlook. I can create a SendMail DTS and execute it to send mail Email works in these scenarios 1. I create a DTS package in SQL Server with just SendMail with the same Profile "ABC" and click Execute and it sends
2
1830
by: Andrew Thompson | last post by:
- NN 4.78 rendering woes, links at far left - I am trying to rework an old site, make it valid html and css, improving the x-browser and 'older browser' compatibility. My efforts so far, have been abysmal. See, for example, this screen shot of the very simple home page, it is not even 10% finished, but I have already run into problems. http://www.physci.org/test/xbrowser/nn478home01.png
0
2100
by: Arun Bhalla | last post by:
I'm having some inconsistency problems with my deployment project ("Setup") and its custom actions ("Installer"). I'm using Visual Studio .NET 2003 (.NET 1.1, no service pack) on Windows XPSP1. My main project is a band object (Explorer Bar) in an assembly (.DLL) that needs to be registered on installation and unregisted on uninstallation. In addition, during installation, Setup creates registry subkeys, sets registry values, installs...
5
1611
by: ma740988 | last post by:
Select parameters in a vendors API file is as follows: #ifdef __cplusplus typedef void (*VOIDFUNCPTR)(...); /* ptr to function returning void */ #else typedef void (*VOIDFUNCPTR)(); /* ptr to function returning void */ #endif /* __cplusplus */
9
1547
by: Mark Rae | last post by:
Hi, This time, I'm looking for a regular expression which says "the string must contain exactly seven or exactly eight digits" e.g. 123456 fails 1234567 passes 12345678 passes 123456789 fails
1
1892
by: hdogg | last post by:
Scope Woes - IF statement nested in WHILE statement -PHP I have an array $actuals_sum. <?php while(conditions) { if($i == '24) {
4
2870
by: =?Utf-8?B?VkIgSm9ubmll?= | last post by:
I am at my witless end here, please help! I have an ASP.Net aspx web page, hosted on Windows Server 2003, that receives a query string with the path to an autocad drawing file selected from a web page hosted on a unix driven file server. The user wants to have this file converted to a pdf. My page takes the query string and turns it into a windows unc path, then I copy the file down to the web server and place it into a directory. This...
1
1390
by: Mike Howarth | last post by:
I've been having a few problems with connecting to SQL Server, initially I was using dblib however found some problems with returning text fields whereby all text fields were ignored and it bawked at multiline sql statements. Having found these major stumbling blocks I've started using pymssql which seems less flaky. One problem I've stumbled across is that I seem to reach my max connections on the database fairly easily (given how my...
0
8683
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8610
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9170
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9031
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8902
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
4623
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2339
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.