Search code examples
c++inheritanceraw-pointer

Error with overload operator>>


Trying to use operator>> for my class plane, and I have an error in my main(). It says that

"no operator ">>" matches these operands    Air.
operand types are: std::istream >> Aircraft *"

my main():

int main()
{
    Aircraft* air[2];
    int choice;
    std::cout << "Plane '1' and Helicopter '2'" << std::endl;
    std::cin >> choice; 
    if (choice == 1)
    {
        Plane p;
        air[0] = new Plane;
        std::cin >> air[0]; //HERE IS AN ERROR
        air[0]->ShowTabl();
        std::cout << air[0];
    }
    /*if (choice == 2)
    {
        //air[1] = new Helicopter;
        //TODO: << and >>  
    }*/
    system("pause");
    return 0;
}

My read():

std::istream& Aircraft::read(std::istream& frFile)
{
    std::cout << "Name: ";
    frFile >> Name;
    std::cout << "Weight: ";
    frFile >> weight;
    return frFile;
}

Operator >>:

it is in (.h):

friend std::istream& operator>> (std::istream& is, Aircraft& A);

it is in (.cpp):

std::istream& operator >> (std::istream& is,  Aircraft& A)
{   
    return A.read(is);
}

As for using in a way , like this ,so it is perfect:

Plane p;
    air[0] = new Plane;
    std::cin >> p; // it's okay

What do I do wrong with this?


Solution

  • Throughout this answer I assume that both Helicopter and Plane publicly inherit from Aircraft. If they don’t, the explanation is still correct but the rest of the advice is probably wrong.

    The line

    Aircraft* air[2];
    

    declares air as an array of two pointers to Aircraft.¹ You probably do want the pointers, despite some of the other comments, because you seem to be working with inheritance so you can’t just use Aircraft directly. So far you only ever have one of them, so I’m less sure that you need an array, but that may be useful later.

    Because air contains pointers to Aircraft instead of directly containing Aircraft, you need to deal with the pointed-to objects at the extra level of indirection. Your stream extraction operator (operator>>) is for an Aircraft, not for an Aircraft*, so if you want to use it with the Plane you allocated on line 10 of your main function, you need to extracted it to the pointed-to Aircraft, *air[0], instead of the pointer, air[0].

    I am not sure how well the Aircraft::read method could work when it isn’t virtual (I would expect you’d also want to read in a Plane-specific property like wingspan), but perhaps you plan to implement that later once you have this part working, which is sensible.

    ¹ You can see this by reading the type from the variable name outward, going to the right before the left. Thus, you see air, go to the right to see [2] meaning “array of two”, followed by * meaning “pointer to”, followed by Aircraft. Knowing this rule helps a lot when you have more complicated types, like functions that accept arrays.