How to Solve Expression Must Have Class Type Error in C++

Shikha Chaudhary Feb 12, 2024
  1. Solved: Expression Must Have Class Type Error in C++
  2. Cause of the Expression Must Have Class Type Error in C++
  3. Fix for the Expression Must Have Class Type Error in C++
  4. Conclusion
How to Solve Expression Must Have Class Type Error in C++

In C++, the dot (.) operator is used for direct member selection, while the arrow (->) operator, on the other hand, is used for indirect member selection. Both these operators have significance, but you must be careful where and how you use them.

This usually depends on whether the object is instantiated using the new operator or not. We will discuss this all but for now, know that the expression must have class type error is one such C++ error that occurs from the incorrect use of the dot (.) operator.

Let us see why this happens and how to resolve it.

Solved: Expression Must Have Class Type Error in C++

To understand the problem statement better, look at the code below. Here, we have a class called Deserts with the function desert() inside it.

In the main block, we define a pointer d to the class Deserts and then use the dot (.) operator with the pointer d to access the class method desert(). But when we run this code, we get an error.

#include <iostream>
using namespace std;

class Deserts {
 public:
  void desert() { cout << "Have a cake!" << endl; }
};

int main() {
  Deserts *d = new Deserts();
  d.desert();
}

Output:

In function 'int main()':
error: request for member 'desert' in 'd', which is of pointer type 'Deserts*' (maybe you meant to use '->' ?)
   15 |     d.desert();
      |       ^~~~~~

This happens because of the incorrect use of the dot (.) operator. Let us quickly revisit the basics of the dot (.) operator to gain more clarity.

the Dot (.) Operator in C++

The dot (.) operator in C++ is used to access the attributes and methods of an object. In other words, we can say that it is used for direct member selection through the object name.

Syntax:

object_name.member_name;

Here is an example that shows how the dot (.) operator works in C++. Here, we have a structure called Desert with two members.

Inside the main block, we create an object d and assign values to the two members of the structure. Now, to print the values of the members of the object d, we use the dot (.) operator, as you can see in lines 12 and 13.

This is essentially how the dot (.) operator works in C++.

To know more about the dot (.) operator in C++, refer to this link.

#include <iostream>
using namespace std;

struct Desert {
  int cookie, cake;
};

int main() {
  struct Desert d = {10, 2};

  cout << "Cookies present:" << d.cookie << endl;  // use dot operator
  cout << "Cakes present  :" << d.cake << endl;    // use dot operator

  return 0;
}

Output:

Cookies present:10
Cakes present  :2

So now think for a minute, can you spot the cause of the error in the previous code? If yes, then kudos to you.

If not, then read on!

Cause of the Expression Must Have Class Type Error in C++

The expression must have class type error occurs when the dot (.) operator, normally used to access the members of an object, is used on a pointer to an object. Think of it like this.

You use the dot (.) operator on a pointer to an object. Now, working as it normally does, the dot (.) operator will try to find the pointer members (fields or methods).

It is common sense that object to a class and pointer to a class are two different things. When we create an object to a class, the class members also become part of the object, but this does not happen when we define a pointer to a class.

Thus, can we say that the pointer is trying to find something that does not even exist?

Absolutely yes, and that is why we get the error.

Fix for the Expression Must Have Class Type Error in C++

We can fix the expression must have class type error in C++ in two ways. Let us discuss them one by one.

Initialize the Object Without the Use of the New Operator to Resolve the Class Type Error in C++

When we use the new operator to initialize an object, we use a pointer, as shown below.

class *object = new class();

So, the first option that we have is to remove the pointer by initializing the object without using the new operator like this:

class object;

Now, let us re-run the problematic code with this change. This time, we instantiate the object without using the new operator, and the code runs fine.

#include <iostream>
using namespace std;

class Deserts {
 public:
  void desert() { cout << "Have a cake!" << endl; }
};

int main() {
  Deserts d;  // Instantiate the object without using the new operator
  d.desert();
}

Output:

Have a cake!

But now, you might wonder if instantiating an object without using the new operator is even the right thing to do. Well, it is.

When we use the new operator to initialize an object, it remains in the memory until we delete it. However, if we do not use the new operator, the object gets destroyed when it goes out of scope.

Thus it is up to you to choose if you want to use the new operator or not, depending on the need. But remember that if you use the new operator, then using the dot (.) operator to access the object members causes an error.

In that case, you should use the arrow (->) operator instead of the dot (.) operator, as discussed in the following section.

Use the Arrow (->) Operator to Resolve the Class Type Error in C++

The arrow (->) operator is used to access the members of an object using a pointer. In other words, the arrow (->) operator is used for indirect member selection via a pointer.

Thus, when we use the new operator to instantiate an object, we should not use the dot (.) operator like this:

pointer_to_object.class_member;

Rather, since a pointer is involved, we should use the arrow (->) operator like this:

pointer_to_object->class_member;

Let us make this change to the problematic code and re-run it. You can see that this time the code runs fine.

#include <iostream>
using namespace std;

class Deserts {
 public:
  void desert() { cout << "Have a cake!" << endl; }
};

int main() {
  Deserts *d = new Deserts();
  d->desert();  // use arrow operator to access the object member via pointer
}

Output:

Have a cake!

Note that using the arrow (->) operator is just a shorthand for the following notation:

(*pointer_to_object).class_member

Can you figure out what this means?

Well, since the dot (.) operator is used on objects and references and not on pointers, the pointer type must be dereferenced first to get the object’s reference. Then, we can use it along with the dot (.) operator to access the object members.

But the better way to do this is to use the arrow (->) operator as it is short and neat.

To know more about the arrow (->) operator in C++, refer to this documentation.

Conclusion

This article taught us about the expression must have class type error in C++. We discussed why this error occurs and the various solutions to fix it.

Related Article - C++ Error