开发者

checking for 'null' slots in a object array

Hi there I have come form the java camp and am trying to do a c++ program

I have an array called Manifest that tak开发者_JAVA百科es passenger objects

for (int i = 0; i< _totalSeats; i++) 
{
    if (Manifest[i] != instanceOf Passenger) {
        cout<<"empty"endl;
    }
    else {
        cout<< PassengerToString(i);
    }
}

obviously the 'instanceOf' is a problem in C++, I know is==null doesn't work as there is no such thing as null without being specificly inserted but to build a blank passenger objects then insert them in each array slot sounds messy and costly. Is there a more elegent way?

thanks


It sounds like you're mapping seats to passengers. This means a map may be a better choice, such as std::map<int, Passenger> Manifest.

for example

#include <map>
#include <string>
#include <iostream>
class Passenger
{
        public:
                std::string toString() const
                {
                        return "Passenger";
                }
};

int main()
{
        std::map<int, Passenger> Manifest;
        Manifest[2] = Passenger();
        int _totalSeats = 10;

         for (int i = 0; i< _totalSeats; i++)
         {
             if (Manifest.count(i))
                     std::cout << Manifest[i].toString() << '\n';
             else
                     std::cout << "empty\n";
         }
}

test run: https://ideone.com/XkNOg


You can't really create an array of objects in C++ without constructing them all (well, actually, you can, but it's ugly, black magic stuff.) Don't use arrays -- use std::vector.


You can have null in C++, provided you hold object pointers.

struct Passenger
{
    std::string name_;
};

std::string PassengerToString(const Passenger& p)
{
    return p.name_;
}


int main() 
{


    const int _totalSeats= 10;
    Passenger* Manifest[_totalSeats]  = {0};

    for (int i = 0; i< _totalSeats;i++)
    {
        if (Manifest[i] != 0)
        {
            std::cout<<"empty" << std::endl;
        }
        else
        {
            std::cout<< PassengerToString(*Manifest[i]) << std::endl;;
        }


    }

    return 0;
}

For real production code, you would use something like shared_ptr<>, but for an exercise in learning C++ post Java, doing this the low level way using raw pointers might be instructive.


The cleanest way, would be to only store objects that are valid in the container. So, instead of using a fixed-size array, you can use a std::vector<Passenger> and add and remove Passengers to it as needed.

If the position of the Passenger objects is important (i.e., the index is important), you can easily use a std::map<int, Passenger>.

Otherwise, there are numerous approaches to solve the problem:

  • Use a container of smart pointers (for example, std::vector<std::unique_ptr<Passenger>> or std::vector<std::shared_ptr<Passenger> >) or a pointer container (for example, boost::ptr_vector<Passenger>) and store pointers to dynamically allocated objects.

  • Use a designated "null object" (the approach you describe). Whether the "null object" is the default state of the object or an explicitly set state is up to you.

  • Use a container of struct { bool valid_; Passenger object_; }; as a crude "optional" type wrapper (this requires Passenger to be default constructible but does not require the default constructed object to be meaningful).

  • Use Boost.Optional


Thank you all for you assistance

I was restricted in what data structures I was allowed to use (I thought a map would have been a much better choice but they chose array....)

here is how I solved the problem in the end

as Friedman-hill so correctly mentioned when I dynamicly created my array it required a blank constructor of type Passenger to initalise. I simply added a private data member bool "isEmpty" initalised to false to my consturctor. then checked like so:

if (!Manifest[i].getIsEmpty())

thanks again

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜