virtual+static

S

sunil

Hi,
I am dealing with problem where I need virtual+static function:

enum {A=0,B=1};

Factory.cpp:
------------------
Base * createInstance(int classType,char *name)
{
if(classType == A)
{
return dynamic_cast<Base *> ( A::getInstance(name));
}
else if(classType == B)
{
return dynamic_cast<Base *> (B::getInstance(name));
}
}

base.cpp:
---------------
class Base {
public:
virtual getInstance(string name)=0; //Pure virtual
};


class A:public Base {
public:
static getInstance(string name)
{
if(name already in objList)
return objinlist;
else
return new A();
}
private:
A(){}
List<A> objList;
}

class B:public Base {
public:
static getInstance(string name)
{
if(name already in objList)
return objinlist;
else
return new B();
}
private:
B(){}
List<B> objList;
}

getInstance() is made static in concrete class as we want it to be able
to create instances of that class (hence it has to be static, since we
all this method on class itself)
getInstance() is made pure virtual in base class since I want to
"enforce" the rule that ever yclass deriving from base must implement
this method. If someone doesnt and tries to create a instance, he will
get compile error.
However above code fails to compile:
The function A::getInstance cannot be both virtual and static. This is
a valid case where I need this functionality from design point of view,
but C++ doesnt allow me to do that. Is there any way I can get around
this?
Thanks,
Sunil
 
V

Victor Bazarov

sunil said:
I am dealing with problem where I need virtual+static function:

enum {A=0,B=1};

Factory.cpp:
------------------
Base * createInstance(int classType,char *name)
{
if(classType == A)
{
return dynamic_cast<Base *> ( A::getInstance(name));

There seems to be no need for the dynamic_cast, conversion from
a pointer to the derived to a pointer to the base class is implicit
and provided by the language.
}
else if(classType == B)
{
return dynamic_cast<Base *> (B::getInstance(name));
}
}

base.cpp:
---------------
class Base {
public:
virtual getInstance(string name)=0; //Pure virtual
};


class A:public Base {
public:
static getInstance(string name)
{
if(name already in objList)
return objinlist;
else
return new A();
}
private:
A(){}
List<A> objList;
}

class B:public Base {
public:
static getInstance(string name)
{
if(name already in objList)
return objinlist;
else
return new B();
}
private:
B(){}
List<B> objList;
}

getInstance() is made static in concrete class as we want it to be
able to create instances of that class (hence it has to be static,
since we all this method on class itself)
getInstance() is made pure virtual in base class since I want to
"enforce" the rule that ever yclass deriving from base must implement
this method. If someone doesnt and tries to create a instance, he will
get compile error.
However above code fails to compile:
The function A::getInstance cannot be both virtual and static. This is
a valid case where I need this functionality from design point of
view, but C++ doesnt allow me to do that. Is there any way I can get
around this?

What happens if you drop the 'getInstance' from 'Base' altogether?

V
 
N

Noah Roberts

sunil said:
The function A::getInstance cannot be both virtual and static. This is
a valid case where I need this functionality from design point of view,
but C++ doesnt allow me to do that. Is there any way I can get around
this?

No, and it would make no sense if there was.

You might find a way to cause a compile error with boost:

template<class sub>
class X
{
public:
X() : { BOOST_STATIC_CHECK((sizeof(sub::create()))); }
};

class Y : public X<Y>
{
};

but then you loose polymorphism.

You might consider that you are using the wrong pattern and try
Prototype instead.

http://en.wikipedia.org/wiki/Prototype_pattern

Check GOF.
 
V

Victor Bazarov

Noah said:
No, and it would make no sense if there was.

You might find a way to cause a compile error with boost:

template<class sub>
class X
{
public:
X() : { BOOST_STATIC_CHECK((sizeof(sub::create()))); }
};

class Y : public X<Y>
{
};

but then you loose polymorphism.

You might consider that you are using the wrong pattern and try
Prototype instead.

http://en.wikipedia.org/wiki/Prototype_pattern

Check GOF.

I don't understand the problem. The OP wants a compile-time error. Where?
While compiling the "createInstance" function (or what's it called?), right?
The function is a [big] switch/case statement for A::blah, B::blah, C::blah
and so on, for every class deriving from 'Base', right? Now, if 'Base' has
'blah', it would be bad. If 'Base' doesn't have 'blah' member (which it
doesn't define anyway, since the proposed one is *pure*), an attempt to call
any of A::blah or B::blah or C::blah (or whatever::blah) would fail and
force
the developer of A, B, C, whatever, to define that function. Am I missing
something here?

"You folks are young, you think the life is simple... But the life is so
much simpler!" -- from an old Russian joke.

V
 
N

Noah Roberts

Victor said:
I don't understand the problem.

He wants to enforce the policy that all subclasses of a type have a
certain static member function. There is no way to do this.
 
V

Victor Bazarov

Noah said:
He wants to enforce the policy that all subclasses of a type have a
certain static member function. There is no way to do this.

It's true that there is no way to do that specifically, but there are
many things in C++ that are not enforceable. For example, there is
no way to enforce that there is a function called 'foo' with a certain
set of arguments and returning void, declared in scope. I can easily
circumvent it with a declaration

void (*foo)(...) = 0;

, right? But if there is no declaration of 'foo' at all, then the
compiler will at least complain if I try calling it. That's why I've
suggested to drop the function from the base class and just make sure
the program tries to call those functions from other classes with the
class name and the :: in front. It won't force the implementor of the
derive classes to add a *static* member *function*, but it will make
him think. And if he resolves it by having a static *pointer* to
function or a static *functor* there, why the hell not?

V
 
P

Pete Becker

Noah said:
Victor Bazarov wrote:




He wants to enforce the policy that all subclasses of a type have a
certain static member function. There is no way to do this.

That's overdesign. The actual requirement is that all derived types that
are used in that factory function must provide that static member
function. And since the factory function calls that function, if it's
not present, it's an error.
 
N

Noah Roberts

Pete said:
That's overdesign. The actual requirement is that all derived types that
are used in that factory function must provide that static member
function. And since the factory function calls that function, if it's
not present, it's an error.

Whatever. I never said what the OP was trying to do was good. I said
it was impossible. The OP has the answer to his question and two
alternatives. If you guys want to bitch about the fact that I answered
the question fine...be my guest.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,060
Latest member
BuyKetozenseACV

Latest Threads

Top