C++ multiple inheritance

Hi, is anyone able to help me understand what the scope operators in main() are doing in this case? On top of that, how is "gc.BonusCharacter::Vehicle::velocity " still able to compile and run since class BonusCharacter is inheriting privately from class Vehicle. Thank you.

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
		struct IMovableObject {};  
	class Vehicle : public IMovableObject 

	{
	public:
		Vehicle(int v) : velocity{ v } {}
		Vehicle() : velocity{ 10 } {}
		int velocity;
		int cunt;
	};
 
	class PlayerCharacter : virtual public Vehicle
	{
	public:
		PlayerCharacter() : Vehicle(10) {}
		virtual ~PlayerCharacter() = default;
	};
	class BonusCharacter : virtual private Vehicle  
	{
	public:
		BonusCharacter() : Vehicle(20) {}
		virtual ~BonusCharacter() = default;
	};

	class GameCharacter final : public BonusCharacter, public PlayerCharacter  
	{
	public:
		Vehicle _vehicle;
		IMovableObject _powerup;
		GameCharacter() : Vehicle(40), BonusCharacter() {}
	};

	int main()
	{
		GameCharacter gc;
		std::cout << gc.BonusCharacter::Vehicle::velocity << std::endl;  
 
 
	}
Last edited on
Please keep the #includes in your code when you post compileable excerpts, as it lets us compile your code without having to type it ourselves.

what the scope operators in main() are doing in this case
The scope resolution operator lets you access whatever identifier is inside that particular scope.
In this case, gc is an object, so you use the . (dot) operator to access its members. Since BonusCharacter is a superclass of GameCharacter, you can explicitly do gc.BonusCharacter::Vehicle instead of gc.Vehicle, but the former is only needed if there is an ambiguity from multiple inheritance.
:: is then used because you're no longer specifying an object on the left-hand side, rather you're specifying a scope (e.g. the scope of Vehicle).

In other words, you're just specifying that you're trying to access the object that is within the GameCharacter object's BonusChararacter::Vehicle scope.

You're doing the same thing as gc.velocity but you're declaring the scopes yourself. Again, using :: is only needed if there is some sort of ambiguity that could arise from using (non-virtual) multiple inheritance.

For example,
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Base { int a; };

struct OtherBase { int a; };

struct Sub : public Base, public OtherBase { };

int main()
{
    Sub sub;
    //sub.a; does not compile: "error: request for member 'a' is ambiguous"
    sub.Base::a;
    sub.OtherBase::a;
}


how is "gc.BonusCharacter::Vehicle::velocity " still able to compile and run since class BonusCharacter is inheriting privately from class Vehicle
I'm not used to seeing this, but I believe the reason is that both PlayerCharacter::Vehicle and BonusCharacter::Vehicle end up pointing to the same object through virtual inheritance, and at least one path is publicly accessible, therefore the compiler allows access.

Your class hierarchy is confusing, to say the least. A GameCharacter both has-a Vehicle, but a GameCharacter also is-a Vehicle?

Also... that's an very questionable variable name you got there in Vehicle. xD
Last edited on
Topic archived. No new replies allowed.