Need help understanding syntax

Okay, so the two pieces of code below are from a couple of questions which I was doing; I think maybe they're probably designed to be slightly confusing, in which case they succeeded. I know the answers, as each piece of code compiles and executes okay, but I don't understand the syntax, and how the output from each is what it is.

Specifically, I don't quite get the static_cast bits. If somebody could explain in beginner-speak how each of the problems works I'd be most appreciative. Thx!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

class A{
  public:
  int work(void){return 4;}
};
class B: public A{
  public:
  int relax(void){return 2;}
};
class C: public A{
  public:
  int relax(void){return 1;}
};

int main(void){
  A *a0 = new A, *a1 = new B, *a2 = new C;
  cout << a0->work() + static_cast<C*>(a2)->relax()
          / static_cast<B*>(a1)->relax() << endl;
  return 0;
}

Output = 4.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;

class A{
  public:
  int p(void){return 2;}
};
class B: public A{
  public:
  int p(void){return 1;}
};

int main(void){
  A *a = new B;
  cout << static_cast<A*>(a)->p() << endl;
return 0;
}

Output = 2

Many thanks.
Last edited on
Where did you get this code? The fact that the programmer wrote "void" in empty parameter lists shows they don't usually use C++.

The first won't compile without the casts since A doesn't have a "relax" function. So you need to say that the A* is really a B* or C*. It's implementing manual polymorphism, I guess. Usually you would define a virtual "relax" function in A so the casts aren't needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

class A {
  public:
    int work() { return 4; }
    virtual int relax() { return 0; }
};

class B : public A {
  public:
    int relax() { return 2; }
};

class C : public A {
  public:
    int relax() { return 1; }
};

int main() {
  A *a = new A, *b = new B, *c = new C;
  std::cout << a->work() + c->relax() / b->relax() << '\n';
}

The second one is casting a pointer-to-A to a pointer-to-A, so the static_cast does nothing.
Last edited on
@Cheddar99,
I'll have a go, but there are better programmers here with more understanding of classes.

In each programme, the pointers are all A *, that is, they may point to either objects of type A ... or the "A part" of classes B and C derived from A. However, on their own, they cannot be used directly to access the member functions "added by" B and C.

The static_cast<type*> will allow them also to access the parts added by the derived classes: e.g. the member function relax() in the first program.

Try the following:
- remove the static_cast in the first programme; then they will fail, because member function relax() is not a part of A, so cannot be accessed via an A *.
- change the static_cast in the second to a <B*>. Then you will get the p() associated with class B.

Now remove the static_cast<A*> in the second program.
- this will give the A version of p(), since a is of type A *.

But now add the word "virtual" in class A:
virtual int p(void){return 2;}
Now an A * pointer knows that this can be overridden by a derived class and run-time polymorphism will allow the dynamic object of type B created by
A *a = new B;
to access the B version of p():
cout << a->p() << endl;
which yields 1.
Last edited on
Hmm, okay, I need to spend some time going over your comments. Thank you both very much. I kinda sorta get what you're each saying, but I want to completely understand it properly, so I'll spend a while going over it all.

@dutch
You asked where the code came from. It's actually from material at:
https://education.cppinstitute.org/

There are quizzes throughout the material they provide, but they sometimes seem rather fond of unnecessarily complicating things, and sometimes using slightly unusual styles of code (as noted in one or two other questions I've asked, and as you noted here).
Last edited on
Topic archived. No new replies allowed.