Можно ли объявить переменную с разными типами в C ++? - PullRequest
1 голос
/ 16 июня 2011

Я пытаюсь объявить переменную следующим образом:

switch(foo){
    case 1:
        MyClass myObject();
        break;
    case 2:
        MyClass2 myObject();
        break;
    case 3:
        MyClass3 myObject();
        break;
}

но в данный момент для компиляции компилятор возвращает следующие ошибки:

  • пересекает инициализацию 'MyClass myObject'
  • конфликтующее объявление 'MyClass2 myObject'
  • «myObject» имеет предыдущее объявление как «MyClass myObject»

есть идеи, чтобы решить эту проблему?

Ответы [ 5 ]

6 голосов
/ 16 июня 2011

Тело оператора switch является одной областью действия. Если вы хотите объявить локальную переменную для единственного case, вам придется создать блок в case с помощью фигурных скобок:

switch (foo) {
  case 1: {
    MyClass myObject();
    break;
  }
  case 2: {
    MyClass2 myObject();
    break;
  }
  case 3: {
    MyClass3 myObject();
    break;
  }
}

Если вы обнаружите, что делаете это часто, вы можете подумать о создании функций для кода в каждом case, чтобы получить код, который легче понять и поддерживать:

switch (foo) {
  case 1:
    HandleCase1();
    break;
  case 2:
    HandleCase2();
    break;
  case 3:
    HandleCase3();
    break;
}
3 голосов
/ 16 июня 2011

Нет, вы не можете сделать что-то подобное. Помимо конфликта имен внутри коммутатора, у вас также есть проблема, что переменная выходит из области видимости, когда вы выходите из коммутатора.

Кроме того, MyClass myObject(); объявляет функцию, возвращающую MyClass. Вы бы объявили переменную как просто MyClass myObject;.

Если вам нужны три разных объекта, возможно, вам следует написать три разные функции. Или, возможно, шаблонная функция, которую можно использовать с разными типами.

0 голосов
/ 16 июня 2011

Вы можете попробовать boost :: option и использовать посетителя:

typedef boost::variant<MyClass1, MyClass2, MyClass3> MyVariantClass;

boost::shared_ptr<MyVariantClass> myObject;
switch (foo) {
    case  1: {
        MyClass1 object();
        myObject = boost::shared_ptr<MyVariantClass>(new MyVariantClass(object))
        break;
    }
   case  2: {
        MyClass2 object();
        myObject = boost::shared_ptr<MyVariantClass>(new MyVariantClass(object))
        break;
    }
    case  3: {
        MyClass3 object();
        myObject = boost::shared_ptr<MyVariantClass>(new MyVariantClass(object))
        break;
    }
}

А затем создайте посетителя, как говорят ребята из Boost в своем уроке. Единственная проблема заключается в том, что вы действительно создаете два объекта. Сам объект в объявлении (MyClass3 object ()), а затем копия, которую делает вариант внутри.

0 голосов
/ 16 июня 2011

Вы можете проверить, что Бо Перссон сказал вам об объявлении переменных здесь . Я думаю, что вы хотите использовать полиморфизм. То есть сделать MyClass1, MyClass2 и MyClass3 производными объектами BaseClass, и тогда вы можете сделать что-то вроде:

BaseClass *myObject;
switch (foo) {
    case  1: {
        myObject = new MyClass1;
        break;
    }
   case  2: {
        myObject = new MyClass2; 
        break;
    }
    case  3: {
        myObject = new MyClass3;
        break;
    }
}

теперь вы можете позволить myObject вести себя как объект, который вы объявили, и его можно использовать не только в рамках этого оператора switch.

0 голосов
/ 16 июня 2011

Чего ты пытаешься достичь?Если вы попытаетесь объявить переменную и использовать ее позже, тогда:

Используйте для этого наследование и Factory.

ParentObject * FactoryCreator::createObject(cstring type){
   ParentObject * theObject = null;
   switch(type){
      case "type1":
          theObject = new ObjectType1();
          break;
      case "type2":
          theObject = new ObjectType2();
          break;
      ...
   }
   return theObject;
}

И из вашего кода.

ParentObject object = FactoryCreator::createObject("type you want");

И вам нужно создать структуру, в которой ParentObject является абстрактным, и все типы объектов наследуются от него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...