构造函数初始化列表使用this指针导致编译错误的问题排查
构造函数初始化列表用
this->导致编译错误的原因及解决办法 错误根源
C++语法明确规定:构造函数的初始化列表里,必须直接写成员变量的名称,不能用this->来限定成员。
初始化列表的语法规则是固定的:
构造函数名(参数): 成员1(值1), 成员2(值2) { ... }
编译器处理初始化列表时,默认你写的就是当前类的成员变量,this->属于表达式层面的语法,根本不符合初始化列表的语法要求,所以会抛出expected identifier before ‘this’这类错误。
简单来说:初始化列表是专门给成员变量做初始化的“专属区域”,这里不需要额外用this指针指明对象,编译器已经默认你操作的是当前类的成员。
修正后的代码
直接把初始化列表里的this->删掉就行,哪怕参数名和成员名重名也没问题——编译器在初始化列表里会优先识别成员变量:
#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): width(width), 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): 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; // 用于浮点数相等判断 // 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); }
额外说明
如果非要用this->来区分成员和参数,只能把赋值操作放到构造函数体里,但这种方式和初始化列表有本质区别:初始化列表是直接初始化成员变量,而函数体里是赋值操作,对于const成员、引用成员这类必须在初始化阶段完成设置的变量,只能用初始化列表,不能用函数体赋值:
// 这种写法可以用this->,但不推荐 Rectangle(float width, float height) { this->width = width; this->height = height; }
所以优先推荐用初始化列表直接写成员名的规范写法。
内容的提问来源于stack exchange,提问作者YuZ
相关产品推荐
相关产品推荐

