简体   繁体   中英

C++ accessing elements of an object stored in a vector

Say for example you have:

class Plant {
    public:
    ...public accessors, etc ...

}

Then you have a specific plant class:

class Broccoli : public Plant
{
    public:
        Broccoli(int i);
        virtual ~Broccoli();

        inline BroccoliSprite* getPlantSprite() { return _plantSprite; };

    private:
         BroccoliSprite* _plantSprite;

};

at some point the Broccoli object is stored in a vector: std::vector<Plant> vPlants;

accessing the vector and its elements I use: inline std::vector<Plant>& getPlants() { return vPlants; }; inline std::vector<Plant>& getPlants() { return vPlants; };

to access:

 for (int f=0; f < _f.getPlants().size(); f++)
 {
    Plant _p1 = _f.getPlants().at(f);

    cocos2d::CCSprite* s = _p1.getPlantSprite();
    ....


 }

I want to be able to use getPlantSprite() to display it to the user but the compiler tells me: No member named 'getPlantSprite' in 'Plant'

This is true, but the object in the vector is of type Plant and contains a member variable that Is the sprite I need, the getter returns it.

What I dont understand is how get access to getPlantSprite()

I guess one thing is I could change class Plant to be class Plant : <some generic object class> and store that object in the vector instead of Plants`

or I could cast to a Broccoli .

UPDATE: So to use shared_ptr<>

I am currently doing:

 Broccoli b(tempField->getFieldNumber()); 
 tempField->getPlants().push_back(b);

This means I would be doing something like:

std::shared_ptr<Plant> object1(new Broccoli(tempField->getFieldNumber()));
tempField->getPlants().push_back(std::move(object1));

How do I now access the Broccoli object inside the shared pointer to do things to it?

Before I used to do something like:

Broccoli b(tempField->getFieldNumber());

tempField->getFieldSprite()->addChild(b.getPlantSprite(), 2);

b.getPlantSprite()->setRotation(BROCCOLI::plantRotation);

tempField->getPlants().push_back(b);

Now:

std::shared_ptr<Plant> object1(new Broccoli(tempField->getFieldNumber()));

tempField->getPlants().push_back(std::move(object1));

b.getPlantSprite()->setRotation(BROCCOLI::plantRotation);

tempField->getPlants().push_back(b);

Compiler says b. is an undeclared identifier which obviously makes sense, but I need to do more to the object after putting it inside the shared_ptr

so this might be:

std::shared_ptr<Plant> object1(new Broccoli(tempField->getFieldNumber()));

tempField->getPlants().push_back(std::move(object1));

object1->getPlantSprite()->setRotation(BROCCOLI::plantRotation);

but the compiler still says: `No member named 'getPlantSprite' in 'Plant'

UPDATE 2: to avoid object slicing, it looks like making functions in base class pure virtual might help solve this, still using shared_ptr or unique_ptr

UPDATE 3:

for (int f=0; f < _f.getPlants().size(); f++)
{
    std::shared_ptr<Plant> sbas = _f.getPlants().at(f);

    std::shared_ptr<Broccoli> sder2 = std::static_pointer_cast<Broccoli>(sbas);

    .. do stuff with `sder2`
}

in this vector there will be things like Broccoli, Asparagus, etc. I will have to use dynamic_pointer_cast, but what does this line look like:

std::shared_ptr<Plant> sbas = _f.getPlants().at(f);

std::shared_ptr<Plant?????> sder2 = std::dynamic_pointer_cast<Broccoli>(sbas);

I do store an internal ID as part of Plant that I could do a switch on to decide what type to statically cast to.....though.

You should be storing shared_ptr<Plant> in your vector, not just Plant . With what you're currently doing, you're getting slicing , which means that you're not actually storing Broccoli s, only the Plant portions thereof (and a cast to Broccoli , as you suggested at the end of your post, will not work).

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