M
ma740988
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_stream(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::string, 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.registerFactory(&class1Factory);
}
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<test*>(factories.create(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.
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_stream(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::string, 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.registerFactory(&class1Factory);
}
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<test*>(factories.create(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.