سؤال

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.

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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;
       }
       //...
    };

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.

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top