Scope issue while creating objects inside if statement if C++ - c++

This is supposed to be very basic.
Layout:
class handler {
public:
handler(Connection *conn) { connection = conn; }
virtual void handle() = 0;
};
class http_status : public handler {
public:
http_status(Connection *conn) : handler(conn) { }
void handle();
};
class http_photoserver : public handler {
public:
http_photoserver(Connection *conn) : handler(conn) { }
void handle();
};
Code:
void pick_and_handle() {
if (connection->http_header.uri_str != "/") {
http_photoserver handler(connection);
} else {
http_status handler(connection);
}
handler.handle();
}
This gives an error:
../handler.cpp:51:10: error: expected unqualified-id before ‘.’ token
I'm guessing because compiler doesn't know what handler is cause object is created inside an if statement. I need to pick a handler based on a condition, how do I do that?
Obviously this code works:
if (connection->http_header.uri_str != "/") {
http_photoserver handler(connection);
handler.handle();
} else {
http_status handler(connection);
handler.handle();
}
But doesn't look very sexy! Is it really the only way in c++?

Use a pointer so you get polymorphic behavior:
auto_ptr<handler> theHandler = (connection->http_header.uri_str != "/") ?
new http_photoserver(connection) :
new http_status(connection);
theHandler->handle();

Of course it's not the only way. But you may have to use pointers:
void pick_and_handle() {
unique_ptr<handler> http_handler;
if (connection->http_header.uri_str != "/")
http_handler.reset(new http_photoserver(connection));
else
http_handler.reset(new http_status(connection));
http_handler->handle();
}
(Instead of unique_ptr, you can use boost::scoped_ptr, shared_ptr, and auto_ptr also. But in this case, unique_ptr and boost::scoped_ptr are most appropriate.)

C++ can only do polymorphism in pointers and references. Note that with your code, the actual type of handler is not known till runtime. The only thing known is that it will be of one of the subtypes of handler, so you have to declare a pointer to use the polymorphism:
void pick_and_handle() {
std::auto_ptr<handler> h;
if (connection->http_header.uri_str != "/") {
h.reset(new http_photoserver(connection));
} else {
h.reset(new http_status(connection));
}
h->handle();
}
I use std::auto_ptr to assure the pointer will be automatically deleted when the function ends.

The object handler doesn't exist outside the scope in which its defined.
One solution could be runtime polymorphism, that is, define a base class and a virtual function in it, as:
struct base_handler
{
virtual void handle(Connection *conn) = 0; //interface
virtual ~base_handler() {} //must make it virtual!
};
struct http_photoserver : base_handler
{
virtual void handle(Connection *conn) {} //implementation
};
struct http_status : base_handler
{
virtual void handle(Connection *conn) {} //implementation
};
Then use it as:
base_handler *phander ;
if (connection->http_header.uri_str != "/") {
phandler = new http_photoserver(connection);
} else {
phandler = new http_status (connection);
}
phandler->handle();
//...
delete phandler;

Declare a pointer somewhere above that code, and then assign an object later in the if statement. Since they are inherited from the same class, OO teaches us that a child can replace a parent :) .
After that it should work.
Just don't forget to destruct! :)
Hope I helped.

If you go with the pointer approach like the others suggest you should also add a virtual destructor the base class.
This approach can be better expressed using a factory method. Just add a static function in your base class that accepts a connection and returns a (smart) pointer to a handler. Put the "pick" logic there.
If you don't want the pointer approach then the second version you posted is the one to use.

Related

Disallow/Redirect C++ delete?

I have a module (dll/so) which exports a single factory function which returns an object then called. Using the interface (pure-virtual) users of the module can then create different objects. All object creation is through the interface, and therefore takes place using the run-time associated with my module and not the application run-time.
As the allocation is taking place inside the module, the deletion also needs to be, because if the application has a different run-time to my module, gpf/segfault time. so I have a "release" member, which performs a self-delete.
void foo::release(void)
{
delete this;
}
Everything is working fine, but it does require that the user of the module behaves.
My question is:
Is it possible to stop someone issuing a delete on my object directly (Or redirect it to delete from my modules memory pool)?
If not as a backup plan, is it possible to detect this in my object, so I can throw an assertion to force good behavior?
E.G:
iFoo* foo = createFoo ();
foo->release(); // Allowed and expected
delete foo; // Disallowed
In the comments to the OP, #dave made a suggestion to declare the destructors in your pure interfaces to be protected instead of public. This would outright prevent external code (that is, external to implementation classes) from invoking delete.
For example:
class IFoo
{
protected:
virtual ~IFoo() { }
public:
virtual void release() = 0;
};
class Foo : public IFoo
{
public:
void release() override
{
delete this;
}
};
IFoo* createFoo()
{
return new Foo();
}
int main()
{
auto foo = createFoo();
foo->release(); // Expected
delete foo; // Cannot access protected destructor of IFoo
Return 0;
}
Since your factory functions only expose the pure interfaces, this approach doesn't break down if an implementation class happens to provide a public destructor. If Foo declared a public destructor, a compiler error would still occur in main because main doesn't know that it's actually dealing with a Foo.
On Edit: This approach only makes it more difficult for users to delete the resource - it doesn't outright prevent it. (I'll refrain from deleting this answer, since it might still be useful.)
If you really want keep someone from invoking delete on your objects, make it illegal for them to do so - return a value type from your factory function.
The value type could be a thin wrapper around the actual object and could provide pointer semantics, a la smart pointers.
A rough example:
class IFoo
{
public:
virtual ~IFoo() { }
virtual void release() = 0;
};
class Foo : public IFoo
{
public:
Foo() { }
void release() override
{
delete this;
}
};
// Value type with pointer semantics
template <class T>
class Undeletable
{
private:
T* m_resource;
public:
Undeletable(T* resource)
: m_resource(resource)
{
}
T* operator->()
{
return m_resource;
}
};
// Old factory function
IFoo* createFoo()
{
return new Foo();
}
// New factory function
Undeletable<IFoo> createSafeFoo()
{
return Undeletable<IFoo>(createFoo());
}
int main()
{
auto foo = createFoo();
foo->release(); // Expected
delete foo; // Possible but DO NOT WANT
auto safeFoo = createSafeFoo();
safeFoo->release(); // Expected
delete safeFoo; // Compiler says NOPE
return 0;
}
Unfortunately, this only obfuscates the fact that the user can still delete the resource. For example:
delete safeFoo.operator->(); // Deletes the resource

How can i accsess different parts of my inherited code

Hi i have a question regarding how to access parts of inherited code.
Say i have this WorldObject that is a base class for alot of other objects. Then i have a class Chest that inherit from WorldObject and also from the abstract class OpenAble, with some methods like open and unlock.
In my main i have a vector of WorldObjects that i iterate through with a for loop. Now to the question, how can i check if a worldobject is also of OpenAble and how can i access the methods in OpenAble.
class WorldObject
{
... //implementation
};
class OpenAble
{
public:
OpenAble(){}
virtual ~OpenAble(){}
virtual void Open() = 0;
virtual void Unlock(int k) = 0;
};
class Chest : public WorldObject, public OpenAble
{
... //implementation
};
main()
{
std::vector<WorldObject> objVector; //vector with several Worldobjects
for (int i =0; i < objVector.Size(); i++)
{
//check if a WorldObject is also of openable
//Do som actions like, open or unlock
//How?
}
};
You could do a dynamic_cast<OpenAble>. This will throw an error if it is the wrong type though which is relatively expensive given that it is quite likely that the object will be the wrong type.
try{
OpenAble& opener = dynamic_cast<OpenAble&>(worldObj);
} catch (std::bad_cast& ex){
//not openable
}
BTW: As pointed out in the comments below, if you use a pointer to the base class in your container instead of references, then you can (and should) use the pointer version of dynamic_cast which will return a null in the case that your object is not OpenAble. Checking that in your case would be a lot more efficient than throwing and catching exceptions.
I would recommend an entirely different approach though. Inject your base class with an "OpenPolicy".
E.g.
class CanOpenPolicy {
public:
boolean canOpen(){ return true; };
boolean canClose(){ return true; };
boolean isOpen(){ return openState; };
void open(){ openState = OPEN; };
void close(){ openState = CLOSED; };
}
class NoOpenPolicy {
public:
boolean canOpen(){ return false; };
boolean canClose(){ return false; };
boolean isOpen(){ return CLOSED; };
void open(){ throw IllegalWorldObjectAction("OpenPolicy disallows operation"); };
void close(){ throw IllegalWorldObjectAction("OpenPolicy disallows operation"); };
}
//injection via template (no need for base "OpenPolicy" class, maybe some
// obscure error codes at compile though)
// Implicit interface based on how you use the injected policy.
template<OpenPol>
class WorldObject {
private:
// CTOR part of the injected contract so you are not tied to knowing how to
// build the policy. This is a key benefit over interface based injection.
OpenPol openPol;
...
public:
...
void open(){
if(openPol.canOpen()){
openPol.open();
}
}
...
}
That's not tested or anything. Just to illustrate the idea. You can add multiple policies for different possible operations and the best thing is that you won't need a lot of hierarchies.
To use it just do something like this:
std::unique_ptr<WorldObject>( new Chest() );
std::unique_ptr<WorldObject>( new Banana() );
std::unique_ptr<WorldObject>( new Chair() );
where:
class Chest : public WorldObject<CanOpenPolicy> {
// Very little implementation in here.
// Most of it is handled in the base class and the injected policies :)
}
class Banana: public WorldObject<CanOpenPolicy> {
}
class Chair : public WorldObject<NoOpenPolicy> {
}
The most important thing, even though you may not like this, is to not throw away type information in the first place.
Collections of generic "object" is a Java'ism, it's not how to do things in C++.
That said, provided the statically known class is polymorphic (has at least one virtual member function), you can use dynamic_cast or typeid. This functionality is known as RTTI, short for Run Time Type Information. With some compilers you have to use special options to enable RTTI.
Idiomatic use of dynamic_cast:
WorldObject* p = ...;
if( auto p_openable = dynamic_cast<OpenAble*>( p ) )
{
// use p_openable
}
Note that dynamic_cast to pointer signals failure by returning a nullpointer, while dynamic_cast to reference signals failure by throwing an exception, since there are no nullreferences.
The simple (obvious) solution is to use dynamic_cast and cast your objects to OpenAble.
The problem with "the simple (obvious) solution" is that usually, use of dynamic_cast shows a lack of flexibility in your class hierarchy and is a symptom of a design problem.
I would offer the OpenAble interface as a set of behavior exposed through a handle:
class OpenAble { /* ... */ };
class WorldObject
{
//implementation
virtual OpenAble* GetOpener() { return nullptr; }
};
class Chest: public WorldObject {
struct ChestOpener: public OpenAble {
Chest *c;
virtual void Open() {
// do stuff with c
}
};
std::unique_ptr<OpenAble> chest_opener;
public:
virtual OpenAble* GetOpener() {
if(!chest_opener) {
chest_opener = new ChestOpener{ this };
}
return chest_opener.get();
}
};
Client code:
std::vector<WorldObject> objVector; //vector with several Worldobjects
for(auto &obj: objVector)
{
if(auto openerHandle = obj.GetOpener())
openerHandle->Open();
}

Dynamically set vector class at runtime

Allow me to give some background. I have an abstract class, Foo.
class Foo {
public:
virtual void bar() = 0;
}
I have two classes that inherit from this class.
class FooOne : public Foo {
public:
void bar();
}
and
class FooTwo : public Foo {
public:
void bar();
}
Now in a completely different class, I want to create an array in a function that can hold instances of one of these two classes. The problem that I'm running into is that I cannot create an array with a dynamic type like this, can I? I'm used to Objective-C where I can create an object of type id.
Ideally, this is what I was looking for (pseudocode):
void someFunction(FooType type) {
class aClass = (type == FooTypeOne ? FooOne : FooTwo);
vector<aClass> container;
// Do something with the container.
}
Note: I cannot use C++11 in this project.
You could use smart pointer in STL container:
Foo* MakeFoo(FooType type)
{
switch(type)
{
case FooTypeOne :
return new FooOne();
break;
case FooTypeTwo :
return new FooTwo();
break;
default:
break;
}
return null;
}
void someFunction(FooType type)
{
std::vector<std::shared_ptr<Foo> > container;
std::shared_ptr<Foo> f_ptr(MakeFoo(type));
container.push_back(f_ptr);
// Do something with the container.
for(std::vector<std::shared_ptr<Foo> >::iterator iter = container.begin();
iter != container.end(); iter++)
{
(*iter)->bar(); // call derived object's bar function respectively
}
}
As you are using C++03, shared_ptr is available under std::tr1
Note:
You need to add virtual destructor to Foo
class Foo {
public:
virtual ~Foo() {}
virtual void bar() = 0;
};
Otherwise, you get undefined behavior if you delete an object of a derived type through a pointer to the base.
The only easy and clean option that I can think of is is templates. i.e if you want to avoid pointers as you say.
template <typename FooType>
void SomeFunction() {
vector<FooType> container;
// Do something with the container.
}
void SomeFunctionCaller(){
...
if(type == "FooOne")
SomeFunction<FooOne>();
else
SomeFunction<FooTwo>();
}
But it is quite different from your design and not sure if it will fit.
Edit: Ah if you are Ok with smart pointers then that is the way to go.

Extending the method pool of a concrete class which is derived by an interface

I had created an interface to abstract a part of the source for a later extension. But what if I want to extend the derived classes with some special methods?
So I have the interface here:
class virtualFoo
{
public:
virtual ~virtualFoo() { }
virtual void create() = 0;
virtual void initialize() = 0;
};
and one derived class with an extra method:
class concreteFoo : public virtualFoo
{
public:
concreteFoo() { }
~concreteFoo() { }
virtual void create() { }
virtual void initialize() { }
void ownMethod() { }
};
So I try to create an Instance of concreteFoo and try to call ownMethod like this:
void main()
{
virtualFoo* ptr = new concreteFoo();
concreteFoo* ptr2 = dynamic_cast<concreteFoo*>(ptr);
if(NULL != ptr2)
ptr2->ownMethod();
}
It works but is not really the elegant way. If I would try to use ptr->ownMethod(); directly the compiler complains that this method is not part of virtualFoo.
Is there a chance to do this without using dynamic_cast?
Thanks in advance!
This is exactly what dynamic_cast is for. However, you can usually avoid using it by changing your design. Since you gave an abstract example, it's hard to judge whether you should be doing things differently.

Converting method signatures

typedef void (__thiscall* LPVOIDPROC) (void);
class ClassA
{
LPVOIDPROC m_pProc;
void SetProc(LPVOIDPROC pProc) { m_pProc = pProc; }
void OnSomeEvent() { m_pProc(); }
}
class ClassB
{
ClassA* pCA;
void Proc() { /* ... */ }
void Init()
{
// Assume pCA != NULL
pCA->Set((LPVOIDPROC)&ClassB::Proc); // error C2440
}
}
How to get rid of this error C2440: 'type cast' : cannot convert from 'void (__thiscall ClassB::* )(void)' to 'LPVOIDPROC' ? I don't want to limit LPVOIDPROC signature to ClassB only. This should be any class and referenced proc should not be static.
Workaround:
typedef void (* CLASSPROC) (void *);
template<class T, void (T::*proc)()>
void class_proc(void * ptr)
{
(static_cast<T*>(ptr)->*proc)();
}
class ClassA
{
CLASSPROC m_pProc;
void * m_pInstance;
public:
void SetProc(void *pInstance, CLASSPROC pProc) {
m_pInstance = pInstance;
m_pProc = pProc;
}
void OnSomeEvent() { m_pProc(m_pInstance); }
};
class ClassB
{
ClassA* pCA;
void Proc() { /* ... */ }
void Init()
{
// Assume pCA != NULL
pCA->SetProc(this, class_proc<ClassB, &ClassB::Proc>);
}
};
I refer you to this link. Your type LPVOIDPROC is a pointer-to-function, which is not the same thing as a pointer-to-member-function. When you try to cast ClassB::Proc, you are trying to convert a pointer-to-member-function, an invalid operation.
You should take a look at boost::function, that offers exactly what you are looking for. Or you could use functors to encapsulate your functions if you don't want to resort to boost. Example:
struct VoidProcFunctor {
virtual void call() = 0;
};
class ClassB;
struct BProcFunctor : VoidProcFunctor {
BProcFunctor(ClassB* b) : b_(b) {}
void call();
private:
ClassB* b_;
}
class ClassA
{
public:
VoidProcFunctor* m_pProc;
void SetProc(VoidProcFunctor* pProc) { m_pProc = pProc; }
void OnSomeEvent() { m_pProc->call(); }
};
class ClassB
{
ClassA* pCA;
void Proc() { /* ... */ }
void Init()
{
// Assume pCA != NULL
// warning! this is not the best design possible
BProcFunctor* bproc = new BProcFunctor(this);
pCA->SetProc(bproc);
}
};
void BProcFunctor::call() { b_->proc() }
Non-static methods require a 'this' pointer, without a 'this' pointer you cannot call it, and so it makes no sense to cast it to a C function pointer.
Consider making a simple class (let's call it X) that has
a data member that refers to a ClassB instance
a () operator (although I prefer methods with clear names) calling ClassB::Proc using the ClassB instance as this-pointer.
Instead of passing a function pointer to class A, make an instance of X (with its datamember to ClassB filled in) and pass this to class A.
Instead of calling a function pointer class A should call x().
Class X could even be written using templates, so if you have this situation for more than one class you must only write it once.
I think that in C# it can be done cleaner using delegates but I leave that to the C# and .Net specialists.
Never cast function pointers. You can end up with stack corruption. Don't do it.
Don't pass pointers to non-static member functions. They use a different calling convention and are not compatible.
In your case, making "Proc()" static might solve the problem.
You need your Proc method to be a static method.