Array of Classes, Inheritance constructor number funky

I am making a program based on a marine eco system. After entering the numbers Plants = 1000, Goldfish = 400, and Redfish = 2; My constructors are not being called for them all. When I print lets say GetMass() it prints material such as

For Plants
Welcome to the Marine System Simulation!
Please enter the number of plants to include in your Marine System: 1000
Please enter the number of Goldfish to include in your Marine System: 400
Please enter the number of Redfish to include in your Marine System: 2
2
1.38242e-038
2
-4.31596e+008
2
1.38242e-038
2
-4.31596e+008
2
1.38242e-038
2
-4.31596e+008
2
1.38242e-038
2
-4.31596e+008
2
1.38242e-038
2
-4.31596e+008
Press any key to continue . . .


Here is the coding
Main()
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
#include <iostream>
#include "Organism.h"
#include "Plant.h"
#include "Fish.h"
#include "Goldfish.h"
#include "Redfish.h"

using namespace std;

int main()
{
	int SimulationTime = 52; //52 Weeks
	int NumRedfish, NumGoldfish, NumPlants;
	Organism *R, *G, *P;
	
	cout << "Welcome to the Marine System Simulation!" << endl;
	cout << "Please enter the number of plants to include in your Marine System: ";
	cin >> NumPlants;
	cout << "Please enter the number of Goldfish to include in your Marine System: ";
	cin >> NumGoldfish;
	cout << "Please enter the number of Redfish to include in your Marine System: ";
	cin >> NumRedfish;

	P = new Plant[NumPlants];
	G = new Goldfish[NumGoldfish];
	R = new Redfish[NumRedfish];

	for(int i = 0; i < 20; i++)
	{
		cout << P[i].GetMass() << endl;
		//cout << G[i].GetMass() << endl;
	}

	

	return 0;
}


Organism()
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
41
42
43
44
45
46
47
#pragma once 

#include <iostream>
using namespace std; 

class Organism
{
public:
    Organism(float StartMass = 1.0f); 
    virtual void Grow() = 0; 
    virtual bool AbleToReproduce() const = 0; 
    virtual void BeginWeek() = 0; 
    virtual void Die(); 
    float GetMass() const; 
    bool IsAlive() const; 
protected:
    void SetMass(float NewMass); 
private:
    float MassInOz; 
    bool Alive; 
}; 

Organism::Organism(float StartMass)
{
	SetMass(StartMass);
	Alive = true;
}

float Organism::GetMass() const
{
	return MassInOz;
}

bool Organism::IsAlive() const
{
	return Alive;
}

void Organism::Die()
{
	Alive = false;
}

void Organism::SetMass(float NewMass)
{
	MassInOz = NewMass;
}


Fish()
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
41
42
43
44
#pragma once

#include "organism.h" 
using namespace std; 

enum FishType {GOLDFISH, REDFISH}; 

class Fish: public Organism 
{
public:
    Fish(float StartSize = 1.0f);
    bool IsHungry() const {return (NeedToEat > EatenThisWeek);}
    void Grow(); 
    bool AbleToReproduce() const; 
    virtual void BeginWeek(); 
    virtual FishType WhatAmI() const = 0; 
    virtual void Reset() = 0; 

protected: 
    float EatenThisWeek, NeedToEat; 
}; 

Fish::Fish(float StartSize)
{
	SetMass(StartSize);
}

void Fish::Grow()
{
	if(IsAlive())
		SetMass(GetMass() + 1);
}

bool Fish::AbleToReproduce() const
{
	if(IsAlive() && !IsHungry())
		return true;
	else
		return false;
}

void Fish::BeginWeek()
{
}


Plant()
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#pragma once 
//Disabling double to float possible loss of data error C4244
#pragma warning(disable : 4244)

#include "organism.h"
using namespace std; 

class Plant: public Organism
{
public:
    Plant(float StartSize = 2); 
    float BeNibbled(); 
    void Grow(); 
    bool AbleToReproduce() const; 
    void BeginWeek();
    void Reset(); 
private:
    float StartMass;
}; 

Plant::Plant(float StartSize)
{
	SetMass(StartSize);
	StartMass = StartSize;
}

void Plant::Grow()
{
	if(IsAlive())
	{
		SetMass(GetMass() * 1.10);
		StartMass = GetMass();
	}
}

float Plant::BeNibbled()
{
	SetMass(GetMass() * .5);
	return GetMass();
}

bool Plant::AbleToReproduce() const
{
	if((StartMass * 0.8) > GetMass())
		return true;
	else
		return false;
}

void Plant::BeginWeek()
{
	Grow();
}

void Plant::Reset()
{
	Plant(2);
}
	



I believe that is all you need to review what might be causing my errors. I hope my coding is understandable and formatted for easy view. I try to keep things clean :-)
Last edited on
I was hoping to be able to keep everything as an Organism, instead I just modified everything so that the directly referenced their own classes. A bit more work but it is working :-\
1
2
3
4
5
6
7
	Organism *R, *G, *P;
	
[snip]

	P = new Plant[NumPlants];
	G = new Goldfish[NumGoldfish];
	R = new Redfish[NumRedfish];


You can't do this.

Plant and Fish are larger types than Organism (sizeof(Plant) > sizeof(Organism))

Say, for example, You have the following sizes (note this is not realistic, I'm just using easy numbers so you can visualize):

sizeof(Organism) == 10
sizeof(Plant) == 12

now when you do new Plant[2]; memory for 2 plants is allocated. One Plant is placed at address 'X', and the other is placed at address X+12. X is then assigned to your 'P' pointer.

The problem here, is that the compiler doesn't know that P points to plants. It thinks it points to Organisms. So when you do P[1], it actually looks at address X+10, not X+12 (it uses sizeof(Organism) instead of sizeof(Plant)). So you're basically getting scrambled data.

Also, this is unrelated but...

1
2
3
4
void Plant::Reset()
{
	Plant(2);
}


This doesn't do what you expect. You can never "reconstruct" an object. ctors are called once and only once.

What this code actually does is it creates a new temporary object and constructs that, but it doesn't actually reconstruct this object. IE: it's basically the same as:

1
2
3
4
void Plant::Reset()
{
       Plant temp(2);
}


only 'temp' is nameless in your code.
Topic archived. No new replies allowed.