c++constructorinitializer-listthis-pointer

Stuck with compilation error with initializer list and this pointer


I have very simple code here with a Rectangle and Circle class inheriting from Shape class, and output their area and perimeter. I can't figure out why it does not compile. The error message says

error: expected identifier before ‘this’ Rectangle(float width, float height): this->width(width), this->height(height){} error expected '{' before 'this

So sth is not correct with my constructor initializer list. Before anyone suggests removal of the "this" pointer, I want to point out I'm aware the this pointer is not mandatory because the initializer can disambiguate. Removing the this pointer compilation goes fine, but I want to keep the this pointer and would like to know exactly what is the problem here.

#include <assert.h>
#include <cmath>

#define PI 3.14159

class Shape{
public:
    virtual float Area() const = 0;
    virtual float Perimeter() const = 0;
};

class Rectangle: public Shape{
public:
    Rectangle(float width, float height): this->width(width), this->height(height){}
    float Area() const{return width*height;}
    float Perimeter() const{return 2*(width+height);}
private:
    float width{0};
    float height{0};
};

class Circle: public Shape{
public:
    Circle(float radius): this->radius(radius){}
    float Area() const{return PI*radius*radius;}
    float Perimeter() const{return 2.0*PI*radius;}
private:
    float radius{0};
};

// Test in main()
int main() {
  double epsilon = 0.1; // useful for floating point equality

  // Test circle
  Circle circle(12.31);
  assert(abs(circle.Perimeter() - 77.35) < epsilon);
  assert(abs(circle.Area() - 476.06) < epsilon);

  // Test rectangle
  Rectangle rectangle(10, 6);
  assert(rectangle.Perimeter() == 32);
  assert(rectangle.Area() == 60);
}

Solution

  • Before anyone suggests removal of the "this" pointer, I want to point out I'm aware the this pointer is not mandatory

    You're misunderstanding the options here. It's mandatory not to have it there. An initializer names the member you initialize. this->width isn't a name, but an expression.

    Correct: Rectangle(float width, float height): width(width), height(height){}