3

I'm stuck with a program I'm writing after a while of fidling around and completing "c++ through game programming" book.

The situation is as follows:

Class A
{
 public:
  A(int x)

 protected:
  int a;

};

A::A(int x):
 a(x)
{}

Class B : public A

Class C : public B
{
 public:
  C(int x)
};

C::C(int x)
{
  A(int x);
}

Am I able to call the constructor of class A in the constructor of class C?

From what I think I know: B is linked to A and C is linked to B so I should be able to get to the constructor of class A from C when I am able to reach member variables and functions by derriving it.

Jens Ackou
  • 151
  • 11
  • 2
    Possible duplicate of [C++ superclass constructor calling rules](http://stackoverflow.com/questions/120876/c-superclass-constructor-calling-rules) – Kiruse Nov 26 '13 at 20:23
  • 1
    Either way, this isn't real code. It won't compile. Don't forget `A::A()` is expecting a parameter. –  Nov 26 '13 at 20:23
  • In this case I would say you should try it and see. The compiler error messages in both clang and g++ are very informative. – David Brown Nov 26 '13 at 20:27
  • I know it's not real code. Just roughly representing what I'm trying to solve. – Jens Ackou Nov 26 '13 at 20:29
  • What's wrong with writing `a=x` in the constructor body of C? – MikeMB Nov 26 '13 at 20:49
  • @MikeMB I altered the code after remyabel's comment. The constructor definition needed a parameter to work. – Jens Ackou Nov 26 '13 at 21:27
  • 1
    @JensAckou: Maybe I missunderstood your question. In essence: no it is not possible to call a constructor of an object after the object has been constructed (and A is constructed before the body of C's ctor is entered). But if you tell us, why you want to call the constructor of a base class, maybe we can provide you with an alternative solution. – MikeMB Nov 26 '13 at 21:50
  • @MikeMB Well that was some kind of confirmation I was looking for. I guess remybel's answer would be a second option even though I'm trying to keep my code as clean as I can get. I'll post a link to the source and some additional explanation in a minute. – Jens Ackou Nov 27 '13 at 00:12
  • @MikeMB http://codeviewer.org/view/code:3965 this is the code I have now in my current project. The purpose of my classes are that I can instantiate from each of them so none are actually considered abstract at the moment and every class in the chain contributes to the fact I won't need to write any methods twice for the same purpose. Also I like to set the name of my object when creating an instance instead of calling a seperate function for setting the string. But I think this is as clean as I will get my constructor approach unless someone has something better up their sleeves. – Jens Ackou Nov 27 '13 at 00:34
  • @Jens I still don't see, why you want to call the constructor of `Object` from within the ctor of `Player`. What information do you want to pass to `Object` that you don't want to make `Actor` aware of? – MikeMB Nov 27 '13 at 09:46
  • Or put differently: If you could call the ctor of `Object` how would your code look like compared to the version presented above? – MikeMB Nov 27 '13 at 09:48
  • @MikeMB You see in the code I posted I instantiate an object and print the name of it. My goal is when I instantiate my player object I pass the name argument between parentheses and this argument gets initialized by the object class. By passing the the argument to actor and then to object, I'm actually done. But I thought I could pass my argument directly to my object class. Which is like it seems impossible to do because player and object are not directly related and player-actor are. So I guess I'll stick with the solution I got now. – Jens Ackou Nov 27 '13 at 11:33
  • 1
    Ok, it's just that I see no advantage in calling the base classes's ctor directly instead of actor's. If you create an `actor` object, you'll want to initialize it with a name, too. So you have to write an appropriate ctor for `actor` anyway. I just want to say that remyabel's solution is the cleanest way to do it, even if C++ would allow calling the BC's ctor directly. – MikeMB Nov 27 '13 at 17:03

1 Answers1

1

You can either try this:

class B : public A
{
public:
    B(int x) : A(x) { }
};

class C : public B
{
public:
    C(int x) : B(x) { }
};

Or if you're lazy (and using C++11):

class B : public A
{
public:
    using A::A(int);
};

class C : public B
{
public:
    using B::B(int);
};

This won't work:

class C : public B
{
public:
    C(int x) : A(x) { }
};

main.cpp: In constructor ‘C::C(int)’:

main.cpp:23:16: error: type ‘A’ is not a direct base of ‘C’

     C(int x) : A(x) { }

                ^

main.cpp:23:19: error: use of deleted function ‘B::B()’

     C(int x) : A(x) { }
  • So if I get this right I must make the jump in B to get in A and it's unpossible to simply call A's constructor from C because the classes are not directly related to eachother. – Jens Ackou Nov 26 '13 at 20:38
  • Because if I instantiate an object from C I know A's constructor is called automatically and it bothers me I need to write all this code in the classes in between A and C. – Jens Ackou Nov 26 '13 at 20:41
  • @Jens I know that `cplusplus.com` isn't a good source, but it seems to be almost identical to your [problem](http://www.cplusplus.com/forum/general/48524/). –  Nov 26 '13 at 20:50
  • Can you give me some more information about the thread you are referring to or a link? – Jens Ackou Nov 26 '13 at 21:32
  • 1
    @Jens I can't seem to find the relevant section in the standard, so I'm going to take a (probably incorrect) guess. `B` implicitly calls `A`'s constructor, and you try to call it again in `C`, which isn't going to work. However, if `B` has nothing important, then you might has well inherit directly from `A`. –  Nov 26 '13 at 21:35