代码之家  ›  专栏  ›  技术社区  ›  Jacobian

boostc++方法返回不同的对象类型

  •  0
  • Jacobian  · 技术社区  · 9 年前

    我想将一些Python代码移植到C++代码。我现在遇到的问题是,一个函数可能返回不同的对象类型,比如一个类或另一个类的变量,这取决于某些条件(但不取决于参数的类型),几乎是这样的:

    def somefunc(var):
      # obj1 is instance of Class1
      # obj2 is instance of Class2
      #.... some other code
      if var == 1:
          return obj1
      elif var == 2:
          return obj2
    

    假设我用C++实现了相应的类。现在我想要的是以某种方式从一个方法返回一个类或另一个类的实例。我不知道如何处理这个任务——我的C++方法应该是什么样子,BOOST_PYTHON_MODULE应该是什么样。如果有人能为世界上最简单的examle提供一个返回不同类实例的C++函数,那将是非常感激的。

    2 回复  |  直到 9 年前
        1
  •  2
  •   Baum mit Augen    9 年前

    正如评论中所说,这里真正的问题是:如何从C++中的同一个函数返回不同的类型?

    我们可以使用 boost.variant 为此。下面是一个小示例,演示了我们需要的基本功能:

    #include <iostream>
    #include <string>
    #include <boost/variant.hpp>
    
    boost::variant<int, std::string> fun (bool i) {
        if (i)
            return "Hello boost!\n";
        return 4711;
    }
    
    int main()
    {
        std::cout << fun(true) << fun(false) << std::endl;
    }
    

    输出将为

    Hello boost!
    4711
    

    更详细地介绍了boost的功能。变体可以在 tutorial .

    如果在编译时不知道可能的返回类型,或者它们的数量很大,我们也可以使用 boost.any 。这更灵活,但有点不太直接:

    #include <iostream>
    #include <string>
    #include <boost/any.hpp>
    
    using namespace std::literals::string_literals;
    
    boost::any fun (bool i) {
        if (i)
            return "Hello boost!\n"s;
        return 4711;
    }
    
    int main()
    {
        std::cout << boost::any_cast<std::string>(fun(true)) 
                  << boost::any_cast<int>(fun(false)) << std::endl;
    }
    

    如果可能,增压。变体很可能是解决问题的更好工具。

        2
  •  1
  •   Springfield762    9 年前

    如果这些类可以从一个接口继承,则可以使用抽象接口类。

    //Interface, abstract class .h file
    
    #pragma once
    
    namespace test
    {
        class IClass0
        {
            public:
                virtual bool DoStuff() =0;      
        };
    }
    
    
    //Class1 .h file
    #pragma once
    #include "IClass0.h"
    
        namespace test
        {
            class Class1 : public IClass0
            {
                public:
                    virtual bool DoStuff();     
            };
        }
    
    
    //Class2 .h file
    #pragma once
    #include "IClass0.h"
    
        namespace test
        {
            class Class2 : public IClass0
           {
                public:
                   virtual bool DoStuff();      
            };
        }
    

    然后,您可以将指针返回到创建的实例作为接口

     unique_ptr<IClass0> ReturnClassInstance()
     {
         if(condition1)
         {
            unique_ptr<Class1> ptr (new Class1());
            return move(ptr);
         }
         else
         {
            unique_ptr<Class2> ptr (new Class2());
            return move(ptr);
         }
     }