1

I undestand that objects instantiated inside of a switch case or an if condition will cease to exist once that block of code has been left (as explained in this question). But what is then the right way to instantiate an object depending on e.g. user input? I believe one can see from the example what I'm (clumsily) trying to do:

class triangle
{
public:
    static const int dimension = 2;
};

class tetrahedron
{
public:
    static const int dimension = 3;
};

template<class T>
class element
{
    public:
    int getDimension()
    {
        return T::dimension;
    }
};

int main()
{
    int elementType;
    std::cout<< "Enter 1 for triangle or 2 for tet: " 
    std::cin >> elementType;

    switch(elementType)
    {
    case 1:
        {
            element<triangle> myElementFile;
            break;
        }
    case 2:
        {
            element<tetrahedron> myElementFile;
            break;
        }
    }
    // I want to use myElementFile further, but it does not exist here
    std::cout<< "The dimension is: " << myElementFile.getDimension(); //this won't work
    return 0;
}

I don't know if the overall approach of using classes as "containers" for storing info about the different elements and then feeding them into a different class is optimal, but I should stick to it for now, because I was told to. :) I am new to c++ and OOP in general. Thank you for any tips!

Community
  • 1
  • 1

3 Answers3

3

The overall solution is to factor your code.

template <typename T>
void process_thing(T const & t)
{
    std::cout << "The dimension is: " << t.getDimension() << "\n";
}

int main()
{
    switch (condition)
    {
    case Triangle:
      {
          process_thing(element<triangle>());
          break;
      }
    case Tetrahedron:
      { 
          process_thing(element<tetrahedron>());
          break;
      }
    default:
      {
          // ...
      }
    };
}

Don't do everything in one function, but separate functional components into distinct pieces of code and compose them logically.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
1

This is the case where you should use polymorphism.

There are two types of polymorphism:

  1. Static, where you use templates and objects are generated during compilation
  2. Dynamic, where you use inheritance and objects are generated on runtime

Both have pros and cons: http://www.cpptutor.com/static-polymorphism-and-dynamic-polymorphism-in-c++.htm

Static approach to your is nicely explained in Kerrek SB's answer.

If you want to create an object and store it for later, I rather recommend using dynamic approach:

enum Elements {
    triangle = 1,
    tetrahedron = 2
}

class Element {
    public:
       virtual int getDimension() = 0;
}

class Triangle : public Element {
    virtual int getDimension() { return 1;}
}

class Tetrahedron : public Element {        
    virtual int getDimension() { return 4;}
}

int main()
{
    Elements elementType;
    std::cout<< "Enter 1 for triangle or 2 for tet: " 
    std::cin >> elementType;


    Element* element = NULL;
    switch(elementType)
    {
    case triangle:
          element = new Triangle();
          break;
    case tetrahedron:
          element = new Tetrahedron();
          break;
    default:
          element = new Tetrahedron();
          break;
    };

    std::cout << "The dimension is: " << element->getDimension() << "\n";
    delete element;

}
Darth Hunterix
  • 1,484
  • 5
  • 27
  • 31
0

One way to solve this is to fully embrace object-oriented programming, and create a base class Element, and then create derived classes triangle and tetrahedron that inherit Element. You can then instantiate the Element as triangle or tetrahedron in the switch statement:

// define base class and derived classes here -- 
// any good book on oo programming will guide you.
//

int main()
{
int     choice = 1;
Element *element;

switch (choice)
{
case 1:
    element = new Triangle ();
    break;

case 2:
    element = new Tetrahedron ();
    break;
}

// do stuff with element here:
std::cout << "Element has " << element.dimensions << "dimensions!" << std::endl;

delete element;
return 0;
}

Good luck!

Steger
  • 887
  • 7
  • 16