2012-01-23 1 views
1

Я очень привык к Java, где я могу создать ArrayList для хранения нескольких объектов, но я не знаю, как это сделать на C++.C++ массив различных объектов? Знать, как это сделать в java

У меня 6 различных объектов: WebcamData UltrasonicData KinectData ImuData GpsData SickData

мне нужно держать экземпляр каждого в одном массиве.

В Java это будет так:

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

и т.д ...

Как я могу сделать подобный массив в C++?

Спасибо

+6

Я считаю это мерзостью. Даже на Java. – pmr

ответ

11

Использование 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:

+0

Подсказка может быть хорошей, что для этого вам нужна библиотека boost. –

+0

Это хороший ответ в некоторых контекстах, но в этом все его вещи называются '* data'. Похоже, ему нужен интерфейс. –

+1

@MooingDuck: все данные в конце; даже «Лук» и «Медведь» в моем примере - это данные. В этом вопросе его данные, похоже, не связаны друг с другом, и нет никакой информации, которую я могу использовать, чтобы дать лучший ответ. – Nawaz

2

C++ не приходит с встроенным в безтипном контейнере или любой механизмом безтипного (короткий из void*). Обычным решением является использование boost::any. Это предполагает, что между этими типами нет общего базового класса. Если есть, вы можете использовать vector указателей на эту базу.

+0

Я никогда не видел boost :: optional используется для этого, у вас есть пример? – juanchopanza

+0

@juanchopanza опционально, любой, вариант. Иногда бывает замешано. – pmr

-1

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

std::vector<void *> myVector; 
+0

Определенно не правильный ответ для большинства контекстов. –

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; 
+0

+1 Классический корпус для полиморфизма. Все они называются xxxData, есть очень хороший шанс, что все они могут быть получены из одного класса, и вы можете хранить shared_ptrs в векторе. – pezcode

0

Вот еще одна реализация.

#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 
0

Я не думаю, что ответы будут полными без упоминания наддува :: варианта.

Вы можете использовать

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

, а затем сохранить их в std::vector<Data>

Затем можно обработать элементы, используя посетителей безопасным способом очень типа.

Смежные вопросы