Base Class Pointers and Class Inheritance

I'm trying to create a series of classes (a base class called Ship, with two derived classes Cruiseship and Cargoship)that will print out different pieces of data from a virtual print function. For Ship it's the ships name and year it was built, for Cruiseship it's the name and amount of passengers, and for Cargoship it's the name and cargo capacity (in tons).

They have to be read from an array of dynamically allocated Ship pointers, which I've made:
1
2
3
4
5
6
7
8
9
10
const int NUM_BOATS = 6;

	Ship *boats[NUM_BOATS] =
	{ new Ship("Minnow", "1964"),
	  new Ship("Queen Anne's Revenge", "1710"),
	  new Cruiseship("Majesty of the Seas", 2744),
	  new Cruiseship("Disney Magic", 2400),
	  new Cargoship("Colombo Express", 93750),
	  new Cargoship("Savannah Express", 107000)
	};


I keep getting errors for 'new' saying that Cruiseship* and Cargoship* cannot be used to initialize an entity of type Ship*. This makes no sense to me, because I based this array off of an example in the book that the assignment specifically said to refer to when making it.

And while I'm here, I keep getting errors in my class header files and cpp files. In the headers, I'm getting a slew of problems, for instance:
1
2
3
4
5
6
7
8
9
10
11
public:
	Cargoship(void);
	~Cargoship(void);

	//Default Constructor
	Cargoship(capacity) : Ship()
	{ capacity = 0; }

	//Constructor
	Cargoship(string cargoName, int cargoCapacity) : Ship (cargoName)
	{ capacity = cargoCapacity; }

In the default constructor ':' keeps getting highlighted, saying it expected an ';' In the constructor the parameter cargoName is highlighted saying it expected a ')'

And in all mt cpp files, my default constructor definitions keep giving errors saying they cannot be redeclared outside their class.
1
2
3
4
5
6
7
8
9
10
11
#include "Cruiseship.h"
//This is my cpp file in its entirety

Cruiseship::Cruiseship(void)
{
}	


Cruiseship::~Cruiseship(void)
{
}


This is my first program involving class inheritance, and I'm very confused. I've been going by examples in the book, but I keep getting errors regardless of how many fixes I try. I appreciate any help anyone can give me.
To give a full answer, can you post a simplified version of your code? Headers and cpp for Ship and Cruiseship, without print, etc functions - just construction and destruction.
The print functions aren't written yet (not even entirely sure what the assignment means when it says 'print function') but here's what I've got.

Ship.h
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
34
#pragma once
#ifndef SHIP_H
#define SHIP_H
#include<iostream>
#include <string>
using namespace std;

class Ship
{
private:
	string name;
	string year;

public:
	Ship(void);
	~Ship(void);

	//Default Constructor
	Ship()
	{
		name = " ";
		year = " ";
	}

	//Constructor
	Ship(string shipName, string yearBuilt)
	{
		name  = shipName;
	}

	Ship(string yearBuilt)
	{
		year = yearBuilt;
	}


Ship.cpp
1
2
3
4
5
6
7
8
9
10
11
#include "Ship.h"


Ship::Ship(void)
{
}


Ship::~Ship(void)
{
}


Cruiseship.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#ifndef CRUISESHIP_H
#define CRUISESHIP_H
#include "ship.h"
class Cruiseship : public Ship
{
private:
	int passengers;

public:
	Cruiseship(void);
	~Cruiseship(void);
	
	//Constructor
	Cruiseship() : Ship()
	{ passengers = 0; }

	//Constructor 2
	Cruiseship(string cruiseName, int cruisePassengers) : Ship(cruiseName)
	{ passengers = cruisePassengers; }


Cruiseship.cpp
1
2
3
4
5
6
7
8
9
10
11
#include "Cruiseship.h"


Cruiseship::Cruiseship(void)
{
}	


Cruiseship::~Cruiseship(void)
{
}


Cargoship.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#include "ship.h"
class Cargoship : public Ship
{
private:
	int capacity;

public:
	Cargoship(void);
	~Cargoship(void);

	//Default Constructor
	Cargoship(capacity) : Ship()
	{ capacity = 0; }

	//Constructor
	Cargoship(string cargoName, int cargoCapacity) : Ship (cargoName)
	{ capacity = cargoCapacity; }


Cargoship.cpp
1
2
3
4
5
6
7
8
9
10
11
#include "Cargoship.h"


Cargoship::Cargoship(void)
{
}


Cargoship::~Cargoship(void)
{
}


And here's my main.cpp in full:
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
#include<iostream>
#include<string>

#include"Cruiseship.h"
#include"Cargoship.h"

using namespace std;

void Print(const Ship *);

int main()
{
	Ship ship;
	Cruiseship cruise;
	Cargoship cargo;

	const int NUM_BOATS = 6;

	Ship *boats[NUM_BOATS] =
	{ new Ship("Minnow", "1964"),
	  new Ship("Queen Anne's Revenge", "1710"),
	  new Cruiseship("Majesty of the Seas", 2744),
	  new Cruiseship("Disney Magic", 2400),
	  new Cargoship("Colombo Express", 93750),
	  new Cargoship("Savannah Express", 107000)
	};

	//Display relevant information for each ship
	for (int count = 0; count < NUM_BOATS; count++)
	{
		Print(boats[count]);
	}
1
2
3
4
5
6
7
8
9
	Ship(void);
	~Ship(void);

	//Default Constructor
	Ship()
	{
		name = " ";
		year = " ";
	}


Ship() and Ship(void) are the same function signature. You are attempting to define the default constructor for Ship twice. You do the same with Cruiseship. In Cargoship you have a default constructor and an attempt at another constructor that takes a parameter -- you neglected to put in the type of the parameter.
Okay so I've taken out the Ship(void) default constructors from both the header and cpp files:

1
2
3
4
5
6
7
private:
	int passengers;

public:
	//Constructor
	Cruiseship() : Ship()
	{ passengers = 0; }


That cleared up a lot of my problems, but I'm still getting weird errors. For instance, in the constuctor up there, it's highlighting "Ship" in Cruiseship() : Ship() saying "Ship is not a non-static data member or base class of class Ship::Cruiseship" That doesn't make sense to me, seeing as when I added the Cruiseship class, I set Ship as its base class.

Also, in my main there are still errors for all the 'new' objects, still telling me things like "A value of type Ship::Cargoship * cannot be used to initialize and entity of type Ship*"

Those are just a couple of the errors I'm getting, and it's frustrating me, especially the array of pointers, because the assignment specified to follow a specific example, saying it would work correct, and it doesn't.

Is there something more basic I'm doing wrong? Have I not set my classes up to inherit correctly or something?

EDIT: Also, I'm not exactly understanding what I did wrong with the cargoship constructor. I realized I forgot to include my #ifndef #define and #endif. Here's what it looks like now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once
#include "ship.h"
#ifndef CARGOSHIP_H
#define CARGOSHIP_H
class Cargoship : public Ship
{
private:
	int capacity;

public:
	
	//Default Constructor
	Cargoship() : Ship()
	{ capacity = 0; }

	//Constructor
	Cargoship(string cargoName, int cargoCapacity) : Ship (cargoName)
	{ capacity = cargoCapacity; }

	//Accessor

};
#endif 
Last edited on
Ship is not a non-static data member or base class of class Ship::Cruiseship


That looks like the compiler thinks Cruiseship is a nested class in Ship. You don't have a forward declaration inside the Ship class for Cruiseship do you?
I don't have anything related to Cruiseship in my Ship.h file. All my current .h and .cpp files are posted a few posts up. I haven't changed anything as of yet.

EDIT: I misspoke. I have gotten rid of the default constructors and destructors built by Visual Studio 2010 (Ship(void) and ~Ship(void)). I also deleted the definitions for the original default constructors and destructors in the .cpp file for each one.
Last edited on
I get the feeling you're not supplying us with the the first error message(s).
The following code results in the same error messages on VS, which I assume you're using because of the pragma once and the intellisense description. Please note in the following code that class Ship's definition is not terminated by the }; that it should be terminated by so the compiler thinks it's not finished with the Ship definition when it gets to Cruiseship. Those error messages are not the first though, because those error messages are caused by trying to inherit from an incomplete type. The way you've supplied your code above doesn't rule out something like this happening.

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
34
35
36
37
38
39
40
#include <iostream>
#include <string>
using namespace std ;

class Ship
{
private:
	string name;
	string year;

public:
    Ship(void) {}
    ~Ship(void) {}

	//Constructor
	Ship(string shipName, string yearBuilt)
	{
		name  = shipName;
	}

	Ship(string yearBuilt)
	{
		year = yearBuilt;
	}

class Cruiseship : public Ship
{
private:
	int passengers;

public:
    Cruiseship(void) {}
    ~Cruiseship(void) {}
	
	//Constructor
	
	//Constructor 2
	Cruiseship(string cruiseName, int cruisePassengers) : Ship(cruiseName)
	{ passengers = cruisePassengers; }
};
Okay...I see what I did wrong here. I feel silly that this all resulted from one misplaced bracket. Stuff like this seems to be a recurring theme for me when it comes to errors in my programs. That one little fix solved all my errors...

One last question. I was told earlier that my Ship(void) default constructors were essentially pointless because I was defining new default constructors. So I deleted the default constructors and there definitions in the Ship, Cruiseship, and Cargoship .cpp files, which left me with some entirely blank .cpp files. Was that the right thing to do if I'm creating new default constructors and defining them in the .h files like I have above?
I feel silly that this all resulted from one misplaced bracket.


One thing to remember when it comes to interpreting the errors your compiler gives you -- the first error is always the most important one. At least some of the following errors will be misinterpretations of the code by the compiler because there was a problem that threw the compiler off with the first.

I was told earlier that my Ship(void) default constructors were essentially pointless because I was defining new default constructors


I told you that you were declaring/defining them twice, which is a different thing than telling you they were useless. It's perfectly acceptable for very simple classes to have no implementation (.cpp) file, but I wouldn't make it a habit. Note that those files are not constricted to just constructors/destructors. You can put any member function definition in the file (provided it isn't also defined in the header file.)

One final thing, Ship is meant to be inherited from so the destructor needs to be virtual. Indeed, from what you're attempting to do with Ship and company I would expect more member functions to be virtual, but I imagine you haven't gotten around to implementing those functions yet.
Last edited on
Topic archived. No new replies allowed.