С++ могу ли я создать производный класс вместо басового, зависящий от аргументов, переданных одному конструктору?

Если у меня есть базовый класс с производным классом, можно ли создавать экземпляры как базовый или производный класс, зависящий от аргументов, переданных в один конструктор?

Пример кода:

//Base Class
class MyClass {
public:
  //All instances created with this constructor
  MyClass(int param1, int param2) {
    if (param1 > param2) { //(for example)
      // TODO - create this object as SubClass instead
    } else {
      //normal base class construction
    }
  }
}

//Derived Class
class SubClass {
public:
  SubClass(int param1, int param2) {
    //Subclass construction
  }

  void function() {
    //function that only works on subclass objects
  }
}

MyClass object1(1, 2); //should create MyClass object
MyClass object2(2, 1); //should create SubClass object

Как показано выше, когда создается экземпляр этого класса, я хочу, чтобы конструктор либо функционировал нормально и создавал класс, либо (в зависимости от значений, заданных в качестве аргументов) создавал его как экземпляр производного подкласса. Обратите внимание, что он должен основываться на значениях различных параметров, а не только на их типах. Можно ли сделать это? При необходимости было бы целесообразно иметь другой производный класс для представления «нормального» варианта (вместо использования класса чистого баса), если когда-либо должен использоваться только один конструктор.

Если это невозможно, я могу просто вызвать конструктор подкласса, когда мне нужен экземпляр этого, но это не идеально, так как мне пришлось бы проверять, какой из них должен создаваться каждый раз, когда он создается, а не просто иметь одну внутреннюю проверку в конструкторе.


person Z Smith    schedule 14.10.2017    source источник
comment
Это то, для чего предназначен шаблон проектирования factory: вы передаете параметры в factory create, и он возвращает либо MyClass, либо Subclass на основе параметров.   -  person mnistic    schedule 14.10.2017


Ответы (2)


Вы можете делегировать создание статической функции MyClass:

class SubClass;

//Base Class
class MyClass {
  MyClass(int param1, int param2) {
  }
public:
  static unique_ptr<MyClass> Create(int param1, int param2) {
    if (param1 > param2) { //(for example)
      return std::make_unique<SubClass>(param,param2);
    } else {
      return std::make_unique<MyClass>(param,param2);
    }
  }
}

//Derived Class
class SubClass : public MyClass {
  SubClass(int param1, int param2) {
    //Subclass construction
  }
public:

  void function() {
    //function that only works on subclass objects
  }
}

std::unique_ptr<MyClass> object1 = MyClass::Create(1, 2); //should create MyClass object
std::unique_ptr<MyClass> object1 = MyClass::Create(2, 1); //should create SubClass object
person user0042    schedule 14.10.2017
comment
Большой! Есть ли способ сделать конструкции по умолчанию статическими? Предполагая, что нет, могу ли я генерировать исключение всякий раз, когда вызывается конструктор (если только не через статический метод), чтобы принудительно использовать статический метод? - person Z Smith; 14.10.2017

Вам нужно использовать ткань. Он вернет указатель на родительский класс в зависимости от ваших параметров. Вы будете работать с ним через интерфейс вашего родительского класса. См. https://en.wikipedia.org/wiki/Abstract_factory_pattern и https://en.wikipedia.org/wiki/Factory_method_pattern

person Vernat Khisamov    schedule 14.10.2017