【问题标题】:Object instantiation inside of switch revisited (c++) [duplicate]重新访问开关内部的对象实例化(c ++)[重复]
【发布时间】:2014-07-17 22:12:07
【问题描述】:

我不明白一旦离开该代码块(如this question 中所述),在 switch case 或 if 条件内实例化的对象将不复存在。但是,根据例如,实例化对象的正确方法是什么?用户输入?我相信人们可以从这个例子中看出我(笨拙地)想要做什么:

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

我不知道将类用作“容器”来存储有关不同元素的信息然后将它们输入不同的类的整体方法是否最佳,但我现在应该坚持下去,因为有人告诉我到。 :) 一般来说,我是 C++ 和 OOP 的新手。感谢您的任何提示!

【问题讨论】:

    标签: c++ class templates switch-statement


    【解决方案1】:

    整体解决方案是分解您的代码。

    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:
          {
              // ...
          }
        };
    }
    

    不要在一个函数中做所有事情,而是将函数组件分成不同的代码片段并按逻辑组合它们。

    【讨论】:

      【解决方案2】:

      在这种情况下,您应该使用多态性。

      有两种类型的多态性:

      1. 静态,您使用的模板和对象在编译期间生成
      2. 动态的,您使用继承并且对象在运行时生成

      各有利弊:http://www.cpptutor.com/static-polymorphism-and-dynamic-polymorphism-in-c++.htm

      Kerrek SB 的回答很好地解释了你的静态方法。

      如果你想创建一个对象并存储它以备后用,我更推荐使用动态方法:

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

      【讨论】:

      • +1 以获得比我更完整的答案!
      • 难道我不必使用element-&gt;getDimension() 而不是element.getDimension(),因为element 是一个指针吗?这样,在类定义后包含分号后,我让它正常工作。
      • 你是对的,我很抱歉这个错误
      【解决方案3】:

      解决这个问题的一种方法是完全拥抱面向对象的编程,并创建一个基类Element,然后创建继承Element的派生类三角形和四面体。然后,您可以在 switch 语句中将 Element 实例化为三角形或四面体:

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

      祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-08
        • 2023-02-06
        • 2022-08-04
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2013-02-01
        相关资源
        最近更新 更多