Home > Back-end >  Why is it not possible to use the dot operator (.) with `this` in C ?
Why is it not possible to use the dot operator (.) with `this` in C ?

Time:01-30

I would like to know why the use of this.var to access internal class variables does not work in my case. I have to resort to Class::var or make use of another way of changing my variables.

In my case this does work:

Vec3D::Vec3D(float x, float y, float z){
    Vec3D::x = x;
    Vec3D::y = y;
    Vec3D::z = z;
    Vec3D::label = "";
}

And so does this:

Vec3D::Vec3D(float x, float y, float z):
            x(x),y(y),z(z){}

However, if I try this:

Vec3D::Vec3D(float x, float y, float z){
    this.x = x;
    this.y = y;
    this.z = z;
    this.label = "";
}

then I get the error:

expression must have class type but it has type "N::Vec3D *"

This is my class definition:

#pragma once
#include <string>

namespace N {
    class Vec3D
    {
    protected:
        float x;
        float y;
        float z;
        std::string label;
    public:
        //Constructors
        Vec3D(float x, float y, float z);
        Vec3D(float x, float y, float z, std::string label);
        Vec3D();
        void show();
     };
}

I would like to know what the cause is of the generated error and how I can improve myself.

CodePudding user response:

It's because this is a pointer. So you need to use it like this: this->x instead of this.x.

CodePudding user response:

this is a pointer to the object, not a reference, nor is it a copy of the object. If an object is behind a pointer, one has to dereference it with the prefix * operator before accessing its members with the . operator; more typically though, one uses the -> operator to perform both at once. C inherited this syntax from C, which in turn has it for pretty tedious historical reasons. Although in case of this specifically, it’s often not even necessary to explicitly mention it from within member functions, as the usual scoping rules will happily resolve bare names to the respective data or function members.

Compare:

#include <iostream>

struct point {
    float x;
    float y;

    void show() {
        // member functions can access data members without
        // explicitly referencing `this`
        std::cout << "(" << x << ", " << y << ")" << std::endl;
    }
};

void foo() {
    point p { 1, 1 };
    point &q = p;
    point *r = &p;

    // modifying p.x through a reference
    q.x = 42;

    // reading p.x through a pointer
    std::cout << r->x << std::endl;
    /*           ↑↑↑↑ equivalent to (*r).x */

    p.show();   // calling a member function on an owned value
    q.show();   // calling a member function through a reference
    r->show();  // calling a member function through a pointer
 /* ↑↑↑↑↑↑↑↑↑ equivalent to (*r).show() */
}

In your example, this has type, Vec3D *, i.e. a pointer to Vec3D. As such, it has to be used like r above, if you use it at all.

CodePudding user response:

this is a pointer to an object belonging to the method you are writing. You must dereference that pointer in order to access the opject. Once you access the object, you can then call a method with the dot operator. The -> operator is just a combo of the dereference operator (*) and the dot operator (.). Example:

Foo* foo = new Foo();

// This line
foo->bar();
// is equivalent to this line
(*foo).bar();

In the last line of the example, I first dereferenced the foo pointer with * to access the object. Then I used . to call a method on the object. The -> does both the dereferencing and the calling of the method.

  •  Tags:  
  • Related