Overloading operator and Inheritance is confusing me!

I am trying to make a program that has one derived class and one base class.

This is the base class header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef Ship_hpp
#define Ship_hpp

#include <stdio.h>
#include <string>
class Ship{
    
    public:
    
        Ship(std::string, std::string);  //Constructor
    
        void setName(std::string);
        std::string getName();
        void setYear(std::string);
        std::string getYear();         //Mutators and accessors...
        
        friend std::ostream& operator<< ( std::ostream&, const Ship& ); 
        //this is the ostream overloaded operator

    private:
    
        std::string name;
        std::string year;
};
#endif 


This is the base class .cpp file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "Ship.hpp"
#include <iostream>
#include <string>

using namespace std;

Ship::Ship( string x, string y)
: name(x), year(y){}

string Ship::getName(){
    
    return name;
}

void Ship::setName( string name_2 ){
    
    name = name_2;
}

string Ship::getYear(){
    
    return year;
}

void Ship::setYear( string year_2){
    
    year = year_2;
}

ostream& operator<< ( ostream& os, const Ship& info ){
    
    return os << "Name: " << info.name << endl << "Year: " << info.year << endl;
}


There's no error in the base class, but it's present in the derived class.
Here's the derived class header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef CruiseShip_hpp
#define CruiseShip_hpp

#include "Ship.hpp"
#include <stdio.h>

class CruiseShip : public Ship {
    
    public:
    
        CruiseShip( int, std::string, std::string );  //Constructor
    
        void setPassengers( int num );
        int getPassengers();             //Mutator and accessor
    
        friend std::ostream& operator<< ( std::ostream&, const CruiseShip& );
        // this is the ostream overloaded operator
    private:
    
        int passengers;
    
};

#endif 


The error code is in the .cpp file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "CruiseShip.hpp"
#include "iostream"

using namespace std;

CruiseShip::CruiseShip( int num, string name, string year ) : Ship( name, year ) {
    
    setPassengers( num );
}

void CruiseShip::setPassengers( int num ){
    
    passengers =  num;
}

int CruiseShip::getPassengers(){
    
    return passengers;
}

ostream& operator<< ( ostream& os, const CruiseShip& info ){
    
    return os << "Name: " << info.getName() << endl << "Passengers: " << info.passengers << endl;
}   //the error is right at the return line saying "Member function 'getName' not viable: 'this' 
     //argument has type 'const CruiseShip', but function is not marked const"


The main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "CruiseShip.hpp"
#include "Ship.hpp"
#include <iostream>
#include <vector>

using namespace std;

int main() {
   
    vector< Ship* > ptr; //I am using vector because I will add more derived 
                         //classes later to add in here
    
    Ship* cruise = new CruiseShip( 50, "David", "2018" );
    
    ptr.push_back(cruise);
    
    cout << *ptr.at[0]; // error here stating "Reference to non-static member function 
                                //must be called
    
}


I want to try to use a simple 'cout' to display the data member "Passenger" from CruiseShip class and the data member "Name" from the base class!

Hope I address my problem clearly and if not, I will add more as I get replies.
Last edited on
You need to make the accessor functions const:
1
2
3
4
5
6
7
8
class Ship{
public:
    Ship(std::string, std::string);
    void setName(std::string);
    std::string getName() const;
    void setYear(std::string);
    std::string getYear() const;
    ...

Also add const at in the same position on the function definitions.

The other error is that you are trying to use the at member function of the vector class, but instead of using parentheses for the argument you've used brackets.
Oh! Thank you for replying!

I did the corrections you pointed out and the output was this:
1
2
Name: David
Year: 2018


But, I want the output to be like this:
1
2
Name: David   //this is the private data member from base class
Passenger: 50     //this is the private data member from derived class 


Is there a way to overload ostream operator in every class while being virtual?
Last edited on
Add this to the base class:
 
    virtual void print(std::ostream& os) const;

and this to the derived class:
 
    void print(std::ostream& os) const;

and define them in place of the operator>> overloads.

Then define a single operator>> like the following. It will call the correct print function depending on the derived type of info
1
2
3
4
ostream& operator<< ( ostream& os, const Ship& info ){
    info.print(os);
    return os;
}


Try this main:
1
2
3
4
5
6
7
int main() {
    vector<Ship*> ptr;
    ptr.push_back(new CruiseShip(50, "David", "2018"));  // derived class
    ptr.push_back(new Ship("Susan", "2012"));            // base class
    for (const auto& x: ptr)
        cout << *x;
}

Last edited on
Wow! I didn't realized you can do that!

It's working as I want it to! Thank you!

Okay, one more minor question, should I put the virtual method in public or private?
closed account (E0p9LyTq)
should I put the virtual method in public or private?

Do you want it to be accessible outside the class? public. Only usable within the class? private.

Your operator<< function is not a part of your class, though it uses your class.

public.
should I put the virtual method in public or private?

As FurryGuy said it depends on whether or not you want to use it from outside the class. In your case you do, so make it public.

And you don't need the friend statement in the class anymore.

closed account (E0p9LyTq)
should I put the virtual method in public or private?

Both print methods, Base class and Derived, should be public.
Topic archived. No new replies allowed.