How to declare an object from a condition and make it accessible 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; 

But since a is declared from inside if, it is not available on the next line. How to eliminate the above condition?

  a.something(); 
+4
source share
5 answers

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

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

The times associated with the const link extend their lifespan to the end of the reference lifetime, so it’s safe. However, you won’t need such hacking (and you can do away with const if you need to change the object) if you have identified problems creating the object and using it in 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 not bound, you can still do this by turning do_something() into 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); } 
+2
source

Two ways I can think of:

1) Make class1 and class2 derived from some base class classB , and 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 cannot change class1 and class2 to add a base class. I also assume that the bit inside do_something more complex than just calling something() on the object in question, otherwise you could just call it directly!

EDIT: just to clarify, the second approach does not make it available throughout the rest of the function in question - it adds a new function in which it is available.

+3
source

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

+2
source

I would recommend putting the something () function as pure virtual in the base class and inheriting from it class1 and class2.

 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 is an example using this method:

 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; } 

As Fred Nurk mentioned in the comments, there are other alternatives for using the delete operator - auto_ptr, various smart raise pointers. They are widely used by many people (including me), which simplifies the life management of objects created with new .

Another edit of the following OP comment:
Remember to add some inclusion protection macros to the headers

 #ifndef _SOME_UNIQUE_NAME_HERE_ #define _SOME_UNIQUE_NAME_HERE_ // header body goes here #endif 

to avoid multiple inclusion (direct or indirect) of your headers in one cpp.

+1
source

There are many ways to approach this, but without additional information, I would probably advise you to do this:

I believe classes have a common ancestor called Base

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

Of course, you shouldn't forget about releasing delete after you no longer need it or use a smart pointer.

If you often repeat this if-else statement, this procedure may be better wrapped in some function or class factory, but it all depends on the circumstances.

+1
source

All Articles