简体   繁体   中英

pass any object to function to create this object

I'm making a small generative video layering software using openframeworks and c++. To this effect I have one main class, one layer class and a lot of different types of video/simulations class. I need to make it so that when I press a key, a different simulation is loaded.

I have two questions:

  1. How can I access a list of all my simulation classes?
  2. Following up, how can I feed one choice from this list into a function that can take any type of object and initiate it?

I made a drawing instead of using to code brackets to have all 3 blocks on the same horizontal level (actual code is underneath).

在此处输入图像描述

Here's the main.cpp and the layer.cpp in code for clarity:

// main.cpp
void ofApp::setup(){
    layer1.setup();
    layer2.setup();
    layer3.setup();
}

void ofApp::update(){
    layer1.update(); 
    layer2.update(); 
    layer3.update(); 
}

void ofApp::draw(){
    layer1.draw(); 
    layer2.draw(); 
    layer3.draw(); 
}

void ofApp::keyPressed(int key){
    switch (key)
    {
    case '1':
        // get first class from list of classes
        layer1.changeSim(); // input first class from list of simulation classes
        break;
    default:
        break;
    }
}

and the layer.cpp

void layer::setup(){
simulation = new Simulation();  // how do i initialize the Simulation variable if I dont know what type itll be ?
}

void layer::update(){
    simulation.update(); 
}

void layer::draw(){
    simulation.draw(); 
}

void layer::changeSim(){
    simulation = new Simulation(); // destroy old simulation and create new one, but will be of a different class
}

Best method to do this is to use something called the factory pattern.

Basically, define a function that takes an argument of some defined type that can be used to figure out what kind of simulation you want, and then create that simulation and return a pointer to it.

A simple version of it might look like this:

enum SimulationType
{
    Simulation_None,
    Simulation_Basic,
    Simulation_Complex,
...
};

Simulation* CreateSimulation(SimulationType Type)
{
    switch(Type)
    {
    case Simulation_None:
    default:
        return nullptr;
    case Simulation_Basic:
        return new BasicSimulation();
    case Simulation_Complex:
        return new ComplexSimulation();
...
    }
}

...

void ofApp::keyPressed(int key){
    switch (key)
    {
    case '1':
        // get first class from list of classes
        layer1.changeSim(Simulation_Basic); // input first class from list of simulation classes
        break;
    default:
        break;
    }
}

...

void layer::setup(){
simulation = CreateSimulation(Simulation_None);
}

void layer::changeSim(SimulationType Type){
    if(simulation) delete simulation;
    simulation = CreateSimulation(Type);
}

This is a simple example - you could also use a table indexed by SimulationType , an ordered map of SimulationType that references static constructor functions for each type, basically anything that associates an identifier with a constructor function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM