Instantiation with Derived Classes

I am developing my own project for the practice. I am having a great deal of difficulty conceptualizing the classes I want. The scenario is that of 2 countries, each capable of producing 2 goods, using 2 factors of production.

Specifically, Lower Mongolia and Upper Mongolia have certain amounts of workers (labor) and machines (capital) with which each can produce some combination of guns and butter. Each good has a selling price, a labor use requirement, and a capital use requirement.

I made classes of the goods with their 3 members. I instantiated with the countries. I decided to use only 1 factor for simplicity. This didn't work because of duplicate variables for each good. By that I mean, the term Lower_Mongolia.price was the same for both guns and butter.

I am considered making a base class called country, having labor and capital as members, with derived classes for the goods, having price, labor use, and capital use, as members. However, I can't find good examples of how to instantiate the country names of Upper Mongolia and Lower Mongolia in the main() section. I still wind up with duplicate variables like Lower_Mongolia.price for both guns and butter.

Is there a way to achieve the organization I want using classes?
closed account (1yvXoG1T)
So if I get this straight, you want your hierarchy to look something like this:
Country
-Upper/Lower Mongolia
--Guns/Butter
---price/labor/capital

If so, then what you would want to do is make the goods objects member of each respective country. Then you would make a call like: Lower_Mongolia.Guns.Price; to access the price of the guns in Lower Mongolia. Don't bother making the goods children of the country class
Yes, Neurotrace.

Then you would make a call like: Lower_Mongolia.Guns.Price; to access the price of the guns in Lower Mongolia.


That is EXACTLY what I want to call in the main() section. I don't know how to instantiate it.
closed account (1yvXoG1T)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "guns.h"
/** Whatever else you need **/

class Country {
     public:
          Guns gunValues; //Or whatever you want to name it. Repeat for any other goods
          /** Rest of class info **/
};

int main() {
     Country Lower_Mongolia;
     Lower_Mongolia.gunValues.SetPrice(50); //This is just to illustrate, you don't HAVE to have this function
     cout << Lower_Mongolia.gunValues.price << endl;

    return 0;
}

Output:
50
Thanks Neurotrace.

Your suggestion has helped me tremendously. I am not quite where I want to be, but I am much closer than I was this morning.
Here is example code. I have a question about it.
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
#include "../../std_lib_facilities.h"

class Goods {
protected:
    double unit_labor;
    double price;
public:
    double getUnit_labor(int country, int goods) {
        if (country == 1 && goods == 1) {unit_labor = 10;}
	if (country == 1 && goods == 2) {unit_labor = 5;}
	if (country == 2 && goods == 1) {unit_labor = 8;}
	if (country == 2 && goods == 2) {unit_labor = 12;}
	return unit_labor;
    }
};

class Apples : public Goods{
public:
};

class Bananas : public Goods {
public:
};


class Country {
public:
    Goods apples;
    Goods bananas;
};


int main() {
    Country home;

    cout << "The labor requirement for apples in the home country is " << home.apples.getUnit_labor(1, 1) << ".\n";
    cout << endl;
	
    cout << "The labor requirement for bananas in the home country is " << home.bananas.getUnit_labor(1, 2) << ".\n";
    cout << endl;

    keep_window_open();
    return 0;
}

1)
I originally had the getUnit_labor() function in the Apples and Bananas classes. However, that yielded a compile error stating that the Country class did not have that function. Why couldn't it find the function in the Apples and Bananas classes? Is it because of the Goods apples line in the Country class? Or is it because I instantiated the 'home' variable in the Country class?

This is an important issue for me because more complex versions of this program will include amount of labor and amount of capital as members of the Country class. There will be getLabor() and getCapital() functions. They should not be in the Goods class.

Thanks.
closed account (1yvXoG1T)
I compiled your code with only minor changes
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
//#include "../../std_lib_facilities.h"
#include <iostream>

using namespace std; // Added this

class Goods {
protected:
    double unit_labor;
    double price;
public:
    double getUnit_labor(int country, int goods) {
        if (country == 1 && goods == 1) {unit_labor = 10;}
	if (country == 1 && goods == 2) {unit_labor = 5;}
	if (country == 2 && goods == 1) {unit_labor = 8;}
	if (country == 2 && goods == 2) {unit_labor = 12;}
	return unit_labor;
    }
};

class Apples : public Goods{
public:
};

class Bananas : public Goods {
public:
};


class Country {
public:
    Goods apples;
    Goods bananas;
};


int main() {
    Country home;

    cout << "The labor requirement for apples in the home country is " << home.apples.getUnit_labor(1, 1) << ".\n";
    cout << endl;

    cout << "The labor requirement for bananas in the home country is " << home.bananas.getUnit_labor(1, 2) << ".\n";
    cout << endl;

    return 0;
}

and everything ran just fine.
Yes. The code as I posted it yesterday runs just fine. But it is not the code that I originally had or that I would like to have. This is the original code that didn't compile.
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
#include "../../std_lib_facilities.h"

class Goods {
protected:
    double unit_labor;
    double price;
public:
};

class Apples : public Goods{                 // move getUnit_labor() from Goods to Apples and Bananas
public:
    double getUnit_labor(int country, int goods) {
        if (country == 1 && goods == 1) {unit_labor = 10;}
	if (country == 1 && goods == 2) {unit_labor = 5;}
	if (country == 2 && goods == 1) {unit_labor = 8;}
	if (country == 2 && goods == 2) {unit_labor = 12;}
	return unit_labor;
    }
};

class Bananas : public Goods {
public:
    double getUnit_labor(int country, int goods) {
        if (country == 1 && goods == 1) {unit_labor = 10;}
	if (country == 1 && goods == 2) {unit_labor = 5;}
	if (country == 2 && goods == 1) {unit_labor = 8;}
	if (country == 2 && goods == 2) {unit_labor = 12;}
	return unit_labor;
    }
};


class Country {
public:
    Goods apples;
    Goods bananas;
};


int main() {
    Country home;

    cout << "The labor requirement for apples in the home country is " << home.apples.getUnit_labor(1, 1) << ".\n";
    cout << endl;
	
    cout << "The labor requirement for bananas in the home country is " << home.bananas.getUnit_labor(1, 2) << ".\n";
    cout << endl;

    keep_window_open();
    return 0;
}

The compiler complained that the function getUnit_labor() was not a member of the class Goods.

On an insight I just got from writing this message, I tested the following code.
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
#include "../../std_lib_facilities.h"

class Goods {
protected:
    double unit_labor;
    double price;
public:
};

class Apples : public Goods{
public:
    double getUnit_labor(int country, int goods) {
        if (country == 1 && goods == 1) {unit_labor = 10;}
	if (country == 1 && goods == 2) {unit_labor = 5;}
	if (country == 2 && goods == 1) {unit_labor = 8;}
	if (country == 2 && goods == 2) {unit_labor = 12;}
	return unit_labor;
    }
};

class Bananas : public Goods {
public:
    double getUnit_labor(int country, int goods) {
        if (country == 1 && goods == 1) {unit_labor = 10;}
	if (country == 1 && goods == 2) {unit_labor = 5;}
	if (country == 2 && goods == 1) {unit_labor = 8;}
	if (country == 2 && goods == 2) {unit_labor = 12;}
	return unit_labor;
    }
};


class Country {
public:
    Apples apples;              // change Goods to Apples and Bananas
    Bananas bananas;
};


int main() {
    Country home;

    cout << "The labor requirement for apples in the home country is " << home.apples.getUnit_labor(1, 1) << ".\n";
    cout << endl;
	
    cout << "The labor requirement for bananas in the home country is " << home.bananas.getUnit_labor(1, 2) << ".\n";
    cout << endl;

    keep_window_open();
    return 0;
}


This code runs as desired. I have an intuitive understanding of how to organize classes to 'encapsulate' variables and functions in a particular manner. But I have no theoretical understanding of why and how C++ works to permit or require that classes be organized that way. I wish I did.

This thread is sort of solved. I am going to leave it open for someone to explain why this last code works.
Last edited on
When you instantiate a derived class, the constructor for the base class is automatically called first, and then the constructor for the derived class. This means when you declare an instance of Apples or Bananas, theGoods class is automatically taken care of.

In the first code you were creating instances of Goods, and that class does not have the function you were trying to call, so that is why you were getting the error.
Tabian, Thank you for your explanation.

I read about constructors and destructors for derived classes and understood in principle about their order of execution. I didn't really understand the consequences of that until your post.

I hadn't realized that constructors were having an impact on my code because I had not created any. But of course, the compiler creates default constructors.

I am a bit torn between trying to further my understanding of derived classes by creating my own constructors, rather than relying on the compiler's default constructors, and furthering the development of my project. However, I expect that somewhere down the road the compiler's default constructors won't be adequate and I will have to write my own.

Still, I will wait a bit because some quick experiments with constructors have yielded the following.

1
2
3
4
5
6
7
8
class Goods {
protected:
    double unit_labor;
    double price;
public:
    Goods(double, double) {};   // constructor
};
...

The above code yielded the following "error C2512: 'Country' : no appropriate default constructor available". This error was attached to the line (45) where 'home' was instantiated to the class 'Country'. Some research revealed that a programmer-defined non-void constructor in one class requires programmer-defined constructors for all classes. (As I understand things.)

1
2
3
4
5
6
7
8
class Goods {
protected:
    double unit_labor;
    double price;
public:
    Goods() {};   // constructor
};
...

Whereas the above code compiles and runs correctly.

So I would have to learn about void and non-void, and, default and explicit, constructors in ordinary classes, base classes, derived classes, and nested classes. It sounds very complicated!


If you have class with a constructor like Goods (double, double){}; then you would create an instance something like this:

Goods bread(1.2, 12.6);

Of course the numbers are just to show that it must have doubles passed to it.

This site has a tutorial that you may find helpful. Look in the section on Object Oriented Programming.

http://www.cplusplus.com/doc/tutorial/

I had read that tutorial a 3 months ago but re-read it this morning. I understood it better the second time. I am marking this thread solved.

I thank Tabian and Neurotrace for helping me on this topic.
Topic archived. No new replies allowed.