根据条件将一个对象声明为多个类

时间:2019-05-24 08:25:43

标签: c++

此问题基于Create objects in conditional c++ statements

但是,在我的情况下,我需要从多个类的选择中声明一个对象,然后将其作为参数传递给函数。因此,必须使用预定义名称(在这种情况下为 obj )声明对象。

Class1 obj;
Class2 obj;

if (...) {
  obj = Class1(); }
if (...) {
  obj = Class1(a, b); }
else
  obj = Class2();

// Do something on declared object
DoSomething(obj.variable_);

当前,由于obj的声明冲突,上述内容将不起作用。我应该怎么做?

4 个答案:

答案 0 :(得分:4)

如果您的对象在运行时不必是“多态的”,则可能不需要std::variant。将代码重构为:

if (...) {
  DoSomething(Class1());
if (...) {
  DoSomething(Class1(a, b));
else
  DoSomething(Class2());

然后将DoSomething用作模板或重载集:

void DoSomething(const Class1&) { }
void DoSomething(const Class2&) { }

答案 1 :(得分:1)

您可以使用std::variant

std::variant<Class1, Class2> var;

if (...) {
  var = Class1(); }
if (...) {
  var = Class1(a, b); }
else
  var = Class2();


std::visit([](auto&& obj) { DoSomething(obj.variable_); }, var); 

该变体一次可以容纳其中一种,这正是您所需要的。并且std::visit允许您将代码通用地应用于任何一种选择,只要可以将通用lambda应用于它即可。

答案 2 :(得分:0)

  

OP说:“ Class1和Class2可以从通用基类继承。我可以提供DoSomething的重载”

继承可以。但仅当它以“子类型化”形式出现时。假设每个人都知道这一点。规范的例子。

在这种情况下,OP的问题和代码实际上是工厂方法的内部。一种解决方案可能是:

 Interface::ptr make ( Interface::subtype which)  
 {
   if ( which == Interface::subtype::one ) 
       return std::make_unique<Class1>();
   return std::make_unique<Class2>();            
 }

用法很简单:

Interface::ptr one = make( Interface::subtype::one  ) ;
Interface::ptr two = make( Interface::subtype::two  ) ;

one->do_something() ;
two->do_something() ;

仅是常见概念的一种变体。 Working code is here

不需要多态性的选项

始终是一个不错的选择。我们不需要继承。我们只需要能够理解消息do_something()的实例即可。

    // no inheritance required
    template<typename T>
      void do_something( T the_t_ ) { the_t_.do_something(); }

同上

    if ( ... ) {
       do_something(Class1{}) ;
    } 
      else if ( ... ) {
      do_something(Class1(a,b)) ;
    } else {
      do_something(Class2());
    }

在这种情况下,Class1和Class2不需要通用的基本类型。

ps:Vittorio的解决方案非常好。当Class1和Class2完全不相关时,也可以应用它。

该变体的一个有趣变体可能是:

if (...) {
  Class1();
if (...) {
  Class1(a, b);
else
  Class2();

没有函数重载DoSomething(),而是键入“做某事”的实例。可能是最可行的设计,但仅适用于某些应用程序。

答案 3 :(得分:0)

使用简单多态性的解决方案,

ClassBase () {
}

Class1 : ClassBase (){
}

Class2 : ClassBase (){
}

然后您可以像使用

ClassBase obj;

if (...) {
  obj = Class1(); }
if (...) {
  obj = Class1(a, b); }
else
  obj = Class2();

// Do something on declared object
DoSomething(obj.variable_);