【问题标题】:C++ array of different objects? Know how to do it in java不同对象的C++数组?知道如何在java中做到这一点
【发布时间】:2012-02-17 00:46:30
【问题描述】:

我非常习惯 Java,我可以创建一个 ArrayList 来保存多个对象,但我不知道如何在 C++ 中做到这一点。

我有 6 个不同的对象: 网络摄像头数据 超声波数据 Kinect 数据 爱慕数据 全球定位系统数据 病态数据

我需要在一个数组中保存每个实例。

在 java 中是这样的:

ArrayList array = new ArrayList();
array.add(new WebcamData);
array.add(new UltrasonicData);

等等……

如何在 C++ 中创建类似的数组?

谢谢

【问题讨论】:

  • 我认为这是可憎的。即使在 Java 中也是如此。

标签: java c++ arrays object


【解决方案1】:

使用std::vector<boost::any>

std::vector<boost::any> miscArray;
miscArray.push_back(Apple());
miscArray.push_back(Onion());
miscArray.push_back(Bear());
miscArray.push_back(Beer());

阅读文档:

boost::any 的实现非常简单,也就是说如果你不能使用 Boost 库,你可以自己实现。

Stackoverflow 上的一个好话题:

【讨论】:

  • 提示您可能需要 boost 库。
  • 在某些情况下这是一个很好的答案,但在这种情况下,他的所有东西都称为*data。看起来他需要一个接口。
  • @MooingDuck:一切归根结底都是数据;在我的示例中,甚至 OnionBear 都是数据。在这个问题中,他的数据似乎不相关,没有太多信息可以用来给出更好的答案。
  • 我认为它们看起来像是数据源并且具有相似的接口。如果不是,那么答案的另一部分是它们不属于同一个容器。
【解决方案2】:

C++ 没有内置无类型容器或任何无类型机制(缺少void*)。通常的解决方案是使用boost::any。这假设这些类型之间确实没有公共基类。如果有,您可以使用 vector 指向该基的指针。

【讨论】:

  • 我从未见过 boost::optional 用于此,你能举个例子吗?
  • @juanchopanza 可选,任何,变体。有时事情会搞混。
【解决方案3】:

如果要添加的所有值都是指针,则可以使用 void 指针:

std::vector<void *> myVector;

【讨论】:

    【解决方案4】:

    我想如果你需要将一些对象放在同一个数组中,这意味着这些对象应该代表一些共同的东西,所以我建议你使用接口并在你的所有类中实现它,这些类将被添加到同一个列表中.在 java 中,你有 Object 类而不是这个接口。所以最后你的代码会是这样的:

    class IMyInterface {
    public:
        virtual ~IMyInterface() {};
        virtual char* getData()=0;
    };
    class WebcamData : IMyInterface {
        /*private stuff*/
    public:
        /*public stuff*/
        virtual char* getData() {/*getData code*/};
        virtual ~WebcamData() {/*destructor code*/};
    }
    
    std::vector< IMyInterface* > _myVector;
    

    【讨论】:

    • +1 多态的经典案例。它们都称为 xxxData,很有可能它们都可以派生自一个类,并且您可以将 shared_ptrs 存储在向量中。
    【解决方案5】:

    这是另一个实现。

     #include <iostream>
    
    class KinectDevices 
    {
         public:
          virtual void On(void) {std::cout << "Kinect is on " << '\n';}
          virtual ~KinectDevices() {std::cout << "  is off" << '\n';}
    };
    
    class kinWebcamData: public KinectDevices 
    {
         public: 
          void On(void) {std::cout << "Webcam  is on" << '\n';}
          ~kinWebcamData(void) { std::cout << "Webcam  " << ' ';}
    };
    
    class kinUltrasonicData: public KinectDevices 
    {
         public: 
          void On(void) {std::cout << "Ultrasonics is on" << '\n';}
          ~kinUltrasonicData(void) {std::cout << "Ultrasonic  " << ' ';}
    };
    
    int main(void)
    {
        const int count = 2;
        // create object array
        KinectDevices *particularKinectDeviceFunction[count];
    
        // create instances of WebcamData()  UltrasonicData()  KinectData() 
        kinWebcamData *WebcamData = new kinWebcamData();
        kinUltrasonicData  *UltrasonicData = new kinUltrasonicData();
    
        //put objects into array
        particularKinectDeviceFunction[0] = WebcamData;
        particularKinectDeviceFunction[1] = UltrasonicData;
    
        particularKinectDeviceFunction[0]->On();
        particularKinectDeviceFunction[1]->On();
    
        delete WebcamData;
        delete UltrasonicData;
    
        std::cout<<" \nPress any key to continue\n";
        std::cin.ignore();
    
        return 0;
    
    }
    

    输出:

    Webcam  is on
    Ultrasonics is on
    Webcam     is off
    Ultrasonic     is off
    
    
    Press any key to continue
    

    【讨论】:

      【解决方案6】:

      如果不提及 boost::variant,我认为答案是不完整的。

      你可以使用

      typedef boost::variant<WebcamData,UltrasonicData,KinectData,ImuData,GpsData,SickData> Data
      

      然后将它们保存在std::vector&lt;Data&gt;

      然后您可以使用访问者以非常类型安全的方式处理元素。

      【讨论】:

        猜你喜欢
        • 2019-01-24
        • 1970-01-01
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-16
        相关资源
        最近更新 更多