0

Coming from a Java/C# background and need a bit of help understanding what is happening here in C++...

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

   void f(int y) {
     cout << x + y << endl;
   }
};

class B : virtual A {
    int x;
    public:
    B(int x) : A(2*x), x(x) {}
    virtual void f(int y){
        cout << x + 2*y << endl;
    }
};

void h(){
    B b(5);
    A &a = dynamic_cast<A &>(b);
    a.f(10);
    b.f
}

void g() {
    A *a = this;
    a->f(10);
    B *b = dynamic_cast<B *>(a);
    b->f(10);
 }

Calling h() is ok but calling g() will not work. Can someone explain why? Also, in the line A(int x) : x(x){} what does : x(x){} do? Same question for B(int x) : A(2*x), x(x) and : A(2*x), x(x).

Thanks so much in advance for your help.

Wes Field
  • 3,291
  • 6
  • 23
  • 26
  • You cannot use `this` in a non-member function. And your `dynamic_cast` will fail because `a` does not point to a `B` object. – juanchopanza Jul 31 '13 at 15:10
  • 2
    What do you expect `this` to refer to in `g()`? As for your second question, that construct is called a "Member initializer list", and is used to supply arguments when constructing the members of the object. – Mankarse Jul 31 '13 at 15:10
  • 4
    You really need to work on the question. Build a small, compilable example that exercises your concern and then ask. – David Rodríguez - dribeas Jul 31 '13 at 15:14
  • I don't expect it to refer to anything, I didn't write this, it is an exam question. h() is supposed to produce output while g() is not. I know 'this' points to nothing. Are there other reasons g() would not work? Perhaps because A is not polymorphic? – Wes Field Jul 31 '13 at 15:36
  • 1
    @WesField: Indeed, the `dynamic_cast` in `g()` would fail even if `a` did point to a valid object of type `B`, since `A` isn't polymorphic. But, as it stands, there are too many errors in the code to say why it "will not work", since we can't guess what "working" is supposed to mean. – Mike Seymour Jul 31 '13 at 16:00
  • @MikeSeymour - To make A polymorphic, would I simply write A with a virtual constructor? Yeah, sorry, it's a crap question. – Wes Field Jul 31 '13 at 16:17
  • There's no such thing as virtual constructor. http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in-c – Iosif Murariu Jul 31 '13 at 16:53
  • 1
    @WesField: To be polymorphic, it needs at least one virtual function. If you don't otherwise need virtual functions, then make the destructor (not the constructor) virtual. You should usually do that anyway, to allow polymorphic deletion. – Mike Seymour Jul 31 '13 at 16:57

4 Answers4

2

A(int x) : x(x){} what does : x(x){} do?

: x(x) is the initializer list. The variable in the paranthesis is the argument received while the outer one is the member variable. It means member variable x is initialized with the value of the x argument received.

B(int x) : A(2*x)

Here you are calling the base class constructor( i.e, A) that receives an integer. x is the variable received by constructor B. This is a way of calling parameterized base class constructor from derived class constructor. By default, derived class constructor invokes the default base class constructor. In your case, if you don't provide the A(2*x) it fails because the base class has no default constructor.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • Thanks for the response. I was under the impression that the compiler would generate a default constructor if none is provided? Is this not true in this case? [Source](https://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr376.htm) – Wes Field Jul 31 '13 at 16:22
  • 1
    If you **create a custom constructor**, the compiler **won't generate** a default constructor. – Iosif Murariu Jul 31 '13 at 16:58
1

g() is just a free function and not a member of a class, so this has no meaning. I'm not exactly sure what you're trying to do there

With regards to:

A(int x): x(x)

Your A class has int x as a member. This is calling the constructor of that integer with the x value that is passed into the constructor of A. In my opinion this is bad style and you should differentiate between the two. For example

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

   //...
};

This is equivalent to

class A {
       int x;
       public:
       A(int x_in)  {
           x = x_in;
       }
       //...
    };
sedavidw
  • 11,116
  • 13
  • 61
  • 95
  • Yes, I realized the this has no meaning. I didn't write this, it is a question on an exam. A poor one, I think. So :A(2*x), x(x) would call assign both A's x and B's x? Still confused about that. – Wes Field Jul 31 '13 at 15:29
  • `A::x` will be 2*x **(the passed x)**, and `B::x` will be the value of the passed x. – Iosif Murariu Jul 31 '13 at 17:00
1

1) As per MSDN (responding to your question related to g());

The this pointer is a pointer accessible only within the nonstatic member functions of a class, struct, or union type. It points to the object for which the member function is called. Static member functions do not have a this pointer.

2) The A(int y) : x(y) {} initializes A::x (the member before () with the value inside the "()" i.e. y (modified variable names for better understanding). Same is the case as with B(int x) : A(2*x), x(x) {}. It calls the base class's (A) constructor with the parameter 2*x and then initializes B::x with the value inside the (), i.e. x.

3) Also, g() wouldn't work because the dynamic_cast<> would throw a compile error since the object that's being casted needs to have at least 1 virtual function. If the only virtual function would be the destructor, then dynamic_cast<> would work.

Iosif Murariu
  • 2,019
  • 1
  • 21
  • 27
  • Ok, so any virtual member function will make A polymorphic? This is different from a pure virtual method, which will make all of A virtual? Is that right? Thanks, first time with C++. – Wes Field Jul 31 '13 at 16:25
  • Having a pure virtual member method (I assume you meant "member" too) in `A` "would help" (since it's virtual), **but you couldn't instantiate any `A`-typed object** because of that pure virtual function. – Iosif Murariu Jul 31 '13 at 16:49
  • maybe this will help http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained – Iosif Murariu Jul 31 '13 at 16:52
0

g is a function at file-scope, aka it doesn't belong to any class. Because of this, you can't use this.

The : x(x)-style expressions are member constructors - they initialize (i.e. call the constructor on) the members of the class.

Drew McGowen
  • 11,471
  • 1
  • 31
  • 57