开发者

How to declare an object from a condition and make it available through the rest of the function?

I have two classes, both with the same function names that do similar things based on user input. I need to do something like this.

if (myapp.advanced == true)
    class1 a;
else
    class2 a;

B开发者_C百科ut since a is declared from inside the if, it's not available in the next line. How do fix the above condition?

 a.something();


Two ways I can think of:

1) Make class1 and class2 derive from some base class classB, then do:

shared_ptr<classB> a;
if(myapp.advanced == true) a.reset(new class1);
else a.reset(new class2);
a->something();

2) Write a template function:

template <typename T> void do_something(T& t)
{
  t.something();
}

...

if(myapp.advanced)
{
  class1 a;
  do_something(a);
}
else
{
  class2 a;
  do_something(a);
}

Note that the second approach is more suitable if you can't change class1 and class2 to add the base class. I'm also assuming that the bit inside do_something is more complicated than just calling something() on the object in question -- otherwise you could just call it directly!

EDIT: Just to clarify, the second approach doesn't make it available throughout the rest of the function in question -- it adds a new function in which it's available instead.


If these types are related, use a common base class and do this:

const base& a = (myapp.advanced == true) ? static_cast<base&>(class1())
                                         : class2();
a.something();
a.some_other_thing();
a.yet_another_thing();

Temporaries bound to a const reference have their lifetimes extended until the end of the reference's lifetime, so this is safe. However, such hackery wouldn't be necessary (and you can do away with the const, if you need to modify the object) if you separated the concerns object creation and object using into different functions:

void do_something(base& obj)
{
  obj.something();
  obj.some_other_thing();
  obj.yet_another_thing();
}

if (myapp.advanced == true) {
    class1 a;
    do_something(a);
} else {
    class2 a;
    do_something(a);
}

If the types are unrelated, you could still do this by turning do_something() into a function templates:

template< class T >
void do_something(T& obj)
{
  obj.something();
  obj.some_other_thing();
  obj.yet_another_thing();
}

if (myapp.advanced == true) {
    class1 a;
    do_something(a);
} else {
    class2 a;
    do_something(a);
}


Your coding logic implies that Class1 and Class2 have something in common. Express this in code by having them derive from a common base class. Then use a base class pointer to hold instances of the derived classes.


There are many ways to approach this, but without further info I would probably advice you to do this:

I suppose the classes have common ancestor called Base

Base* a;
if (myapp.advanced == true)
    a = new class1();
else
    a = new class2();

Of course you must not forget to issue a delete after you no longer need it or use a smart pointer.

If you find yourself repeating this if-else statement often, this procedure might be better of wrapped in some sort of function or factory class, but it all depends on the circumstances.


I would recommend putting function something() as pure virtual to base class and inherit class1 and class2 from it.

class Base
{
public:
    virtual void something() = 0;
    virtual ~Base(){}; // since we use Base class pointer the destructor should be virtual
};

class class1 : public Base
{
public:
    void something(){ //do stuff
    }
};
class class2 : public Base
{
public:
    void something(){ //do other stuff
    }
};

Here's a sample of usage of this technique:

int main()
{    
    Base* a = NULL;

    if (myapp.advanced == true)
        a = new class1();
    else
        a = new class2();

    a->something();

    // when the instance is not needed anymore destroy it.
    delete a;
}

Like Fred Nurk mentioned in the comments there's other alternatives for using delete operator - auto_ptr, different boost smart pointers. They're widely used by many people (including myself) making it easier to control the life of objects created with new.

Another edit following OP's comment:
Don't forget to put multiple inclusion protection macro in your headers

#ifndef _SOME_UNIQUE_NAME_HERE_
#define _SOME_UNIQUE_NAME_HERE_

// header body goes here

#endif

to avoid multiple including (direct or indirect) of your headers into one cpp.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜