Is there a way to share a variable between instances of a class, but not between instances of the class containing it?

Let's say I have a class named 'City' and a nested class inside of it called 'House', and I want that the color of every house in the same city would always be identical. It would be a waste of memory to make a color variable inside class 'House', as every color of every house in the same city would have the same value. If I'd make the color variable inside 'City' instead, it would be accessible to the entire class, and I don't 'Parks' or 'Restaurants' to have access to 'color_of_houses'.
The third option is to make it static variable inside of 'House', the problem now is that the houses of every other city would have the same color as well.
Is there some kind of keyword that makes a variable shared between instances of a class, but not between instances of the class that contains it?

Example for what I'm looking for:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <conio.h>

class City
{
public:
	class House
	{
	public:
		keyword int color;
	} house_a, house_b;
};

int main()
{
	City city_a, city_b;
	city_a.House::color = 5;
	city_b.House::color = 13;

	return 0;
}
If I'd make the color variable inside 'City' instead...

I think this is what you want
...it would be accessible to the entire class, and I don't 'Parks' or 'Restaurants' to have access to 'color_of_houses'.

Yes, it would be accessible to City. No, it would not be accessible to other embedded classes you might have inside City, unless this variable was public (bad practice) static or the embedded class held a reference to its City.

Edit: corrected behavior
Last edited on
It wouldn't be accessible to their instances, but it would be accessible to the classes themselves, it would also be accessible to functions of 'City'. Besides, other nested classes inside 'City' might need to have their own shared variables as well, having them all inside 'City' could get messy.

Also, using the same practice for 'City' (for variables such as 'size_of_city', in case I want all cities to be at the same size) means I have to make them global variables, which again brings up the accessibility issue. Although I could use the static keyword in this case, as the problem is only with nested classes, I'd like to use a more uniform practice, instead of using different methods for nested and non-nested classes.
Why do you have nested classes at all?

Why not:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <vector>

class House
{
  // code
};

class City
{
  std::vector<House> houses;
  Color house_color = pink;
public:
  // interface
};

int main()
{
  City city_a;
  City city_b( blue );
}
You can do what you asked (share a variable) with a static variable that both classes can use, one of the classes can own it or it can be outside both or in its own class. This is pretty much going around OOP to make a pseudoglobal and it can have all the problems of a global if used poorly. I am not one to tell you what to do and what not to, the technique feels wrong if you are a stickler for OOP designs, but you CAN do it and it works just fine. It seems like a valid pattern IFF you have one class as the owner of it and the other class only as a 'reader' of it.
Last edited on
keskiverto,
Doesn't 'House' lack access to 'house_color' that way though? What if I want to add a function inside 'House' that uses this variable?
Besides, now it's possible to make a 'House' outside of a 'City', as every element in the code as access to it.

Is it perhaps possible to somehow make variables accessible only to specific members?
For example:
1
2
3
4
5
6
7
8
9
10
vector2<int> city_size; //somehow only accessible to City
class City
{
	Color house_color; //somehow only accessible to House
	class House
	{
	public:
		static int color;
	} house_a, house_b;
};
The question is, who paints houses?

Does the rest of the program even know that there are houses, if the City does all the work?

If you wanted to stuck to your original plan, you could try by nesting your class into an intermediate one:

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
62
63
64
65
66
67
68
#include <iostream>

class City {
public:
    struct House_shared {
        House_shared(const City& myplace_arg, int color_arg);
        struct House {
            House(const House_shared& hs_arg);
            int getColor() const { return hs.color; }
        private:
            const House_shared& hs;
        };
        House house_a, house_b;
    private:
        const City& myplace;
        int color;
    };
    struct Park_shared {
        Park_shared(const City& myplace_arg, int color_arg);
        struct Park {
            Park(const Park_shared& ps_arg);
            int getColor() const { return ps.color; }
        private:
            const Park_shared& ps;
        };
        Park park_a, park_b;
    private:
        const City& myplace;
        int color;
    };
    City(int house_color = 1, int park_color = 2);
    House_shared hs;
    Park_shared ps;
};

City::City(int house_color, int park_color)
    : hs { *this, house_color },
      ps { *this, park_color }
        {}

City::House_shared::House_shared(const City& myplace_arg, int color_arg)
    : house_a { *this }, house_b { *this },
      myplace { myplace_arg }, color { color_arg }
        {}

City::House_shared::House::House(const House_shared& hs_arg) : hs { hs_arg } {}

City::Park_shared::Park_shared(const City& myplace_arg, int color_arg)
    : park_a { *this }, park_b { *this },
      myplace { myplace_arg }, color { color_arg }
        {}

City::Park_shared::Park::Park(const Park_shared& ps_arg) : ps { ps_arg } {}

int main()
{
    City city_a(13, 14), city_b(666, 667);
    std::cout << "\ncity_a.hs.house_a::color: " << city_a.hs.house_a.getColor()
              << "\ncity_a.hs.house_b::color: " << city_a.hs.house_b.getColor()
              << "\ncity_a.ps.park_a::color: " << city_a.ps.park_a.getColor()
              << "\ncity_a.ps.park_b::color: " << city_a.ps.park_b.getColor()
              << "\ncity_b.hs.house_a::color: " << city_b.hs.house_a.getColor()
              << "\ncity_b.hs.house_b::color: " << city_b.hs.house_b.getColor()
              << "\ncity_b.ps.park_a::color: " << city_b.ps.park_a.getColor()
              << "\ncity_b.ps.park_b::color: " << city_b.ps.park_b.getColor()
              << '\n';
    return 0;
}


Output:
city_a.hs.house_a::color: 13
city_a.hs.house_b::color: 13
city_a.ps.park_a::color: 14
city_a.ps.park_b::color: 14
city_b.hs.house_a::color: 666
city_b.hs.house_b::color: 666
city_b.ps.park_a::color: 667
city_b.ps.park_b::color: 667


Anyway, I think keskiverto has already directed you towards a far better solution: a “City” should contain several “House”(s), which consequentially should be declared before “City”, not inside it.
Topic archived. No new replies allowed.