해결됨: 표현식에 C++의 클래스 유형 오류가 있어야 함

Shikha Chaudhary 2023년10월12일
  1. 해결됨: 표현식에 C++의 클래스 유형 오류가 있어야 함
  2. 식의 원인은 C++에서 클래스 유형 오류가 있어야 합니다.
  3. 식에 대한 수정 사항은 C++에서 클래스 유형 오류가 있어야 함
  4. 결론
해결됨: 표현식에 C++의 클래스 유형 오류가 있어야 함

C++에서 점(.) 연산자는 직접 멤버 선택에 사용되는 반면 화살표(->) 연산자는 간접 멤버 선택에 사용됩니다. 이 두 연산자 모두 의미가 있지만 사용 위치와 방법에 주의해야 합니다.

이것은 일반적으로 객체가 new 연산자를 사용하여 인스턴스화되는지 여부에 따라 다릅니다. 이것에 대해 모두 논의하겠지만 지금은 expression must have class type 오류가 점(.) 연산자를 잘못 사용하여 발생하는 C++ 오류 중 하나라는 것을 알고 있습니다.

왜 이런 일이 발생하고 해결 방법을 알아보겠습니다.

해결됨: 표현식에 C++의 클래스 유형 오류가 있어야 함

문제 설명을 더 잘 이해하려면 아래 코드를 살펴보십시오. 여기에는 desert() 함수가 포함된 Deserts라는 클래스가 있습니다.

main 블록에서 Deserts 클래스에 대한 포인터 d를 정의한 다음 포인터 d와 함께 점(.) 연산자를 사용하여 클래스 메서드 desert()에 액세스합니다. 하지만 이 코드를 실행하면 오류가 발생합니다.

#include <iostream>
using namespace std;

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

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

출력:

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();
      |       ^~~~~~

이것은 점(.) 연산자를 잘못 사용했기 때문에 발생합니다. 더 명확하게 이해하기 위해 점(.) 연산자의 기본 사항을 빠르게 다시 살펴보겠습니다.

C++의 점(.) 연산자

C++의 점(.) 연산자는 개체의 특성과 메서드에 액세스하는 데 사용됩니다. 즉, 개체 이름을 통해 직접 멤버를 선택하는 데 사용된다고 할 수 있습니다.

통사론:

object_name.member_name;

다음은 점(.) 연산자가 C++에서 작동하는 방식을 보여주는 예입니다. 여기에 멤버가 두 개인 Desert라는 구조가 있습니다.

main 블록 내에서 객체 d를 생성하고 구조의 두 멤버에 값을 할당합니다. 이제 개체 d의 멤버 값을 인쇄하기 위해 점(.) 연산자를 사용합니다. 12행과 13행에서 볼 수 있습니다.

이것은 기본적으로 점(.) 연산자가 C++에서 작동하는 방식입니다.

C++의 점(.) 연산자에 대한 자세한 내용은 링크를 참조하십시오.

#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;
}

출력:

Cookies present:10
Cakes present  :2

이제 잠시 생각해보세요. 이전 코드에서 오류의 원인을 찾을 수 있습니까? 그렇다면 찬사를 보냅니다.

그렇지 않다면 계속 읽어보세요!

식의 원인은 C++에서 클래스 유형 오류가 있어야 합니다.

expression must have class type 오류는 일반적으로 개체의 멤버에 액세스하는 데 사용되는 점(.) 연산자가 개체에 대한 포인터에 사용될 때 발생합니다. 이렇게 생각해보세요.

개체에 대한 포인터에 점(.) 연산자를 사용합니다. 이제 정상적으로 작동하면서 점(.) 연산자가 포인터 멤버(필드 또는 메서드)를 찾으려고 시도합니다.

클래스에 대한 객체와 클래스에 대한 포인터가 서로 다른 두 가지라는 것은 상식입니다. 클래스에 대한 객체를 만들 때 클래스 멤버도 객체의 일부가 되지만 클래스에 대한 포인터를 정의할 때는 이런 일이 발생하지 않습니다.

따라서 포인터가 존재하지도 않는 것을 찾으려고 한다고 말할 수 있습니까?

물론 그렇습니다. 그래서 오류가 발생합니다.

식에 대한 수정 사항은 C++에서 클래스 유형 오류가 있어야 함

두 가지 방법으로 C++에서 expression must have class type error를 수정할 수 있습니다. 하나씩 논의해 봅시다.

New 연산자를 사용하지 않고 개체를 초기화하여 C++에서 클래스 유형 오류 해결

객체를 초기화하기 위해 new 연산자를 사용할 때 아래와 같이 포인터를 사용합니다.

class *object = new class();

따라서 첫 번째 옵션은 다음과 같이 new 연산자를 사용하지 않고 개체를 초기화하여 포인터를 제거하는 것입니다.

class object;

이제 이 변경으로 문제가 있는 코드를 다시 실행해 보겠습니다. 이번에는 new 연산자를 사용하지 않고 개체를 인스턴스화하고 코드가 제대로 실행됩니다.

#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();
}

출력:

Have a cake!

그러나 이제 new 연산자를 사용하지 않고 개체를 인스턴스화하는 것이 옳은 일인지 궁금할 수 있습니다. 글쎄요.

new 연산자를 사용하여 개체를 초기화하면 삭제할 때까지 메모리에 남아 있습니다. 그러나 new 연산자를 사용하지 않으면 객체가 범위를 벗어날 때 소멸됩니다.

따라서 필요에 따라 new 연산자를 사용할지 여부를 선택하는 것은 사용자에게 달려 있습니다. 그러나 new 연산자를 사용하는 경우 객체 멤버에 액세스하기 위해 점(.) 연산자를 사용하면 오류가 발생합니다.

이 경우 다음 섹션에서 설명하는 것처럼 점(.) 연산자 대신 화살표(->) 연산자를 사용해야 합니다.

화살표(->) 연산자를 사용하여 C++에서 클래스 유형 오류 해결

화살표(->) 연산자는 포인터를 사용하여 객체의 멤버에 액세스하는 데 사용됩니다. 즉, 화살표(->) 연산자는 포인터를 통한 간접 멤버 선택에 사용됩니다.

따라서 new 연산자를 사용하여 개체를 인스턴스화할 때 다음과 같이 점(.) 연산자를 사용하면 안 됩니다.

pointer_to_object.class_member;

오히려 포인터가 관련되어 있으므로 다음과 같이 화살표(->) 연산자를 사용해야 합니다.

pointer_to_object->class_member;

문제가 있는 코드를 이렇게 변경하고 다시 실행해 보겠습니다. 이번에는 코드가 제대로 실행되는 것을 볼 수 있습니다.

#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
}

출력:

Have a cake!

화살표(->) 연산자를 사용하는 것은 다음 표기법의 속기일 뿐입니다.

(*pointer_to_object).class_member

이것이 무엇을 의미하는지 알 수 있습니까?

음, 점(.) 연산자는 포인터가 아닌 개체와 참조에 사용되므로 먼저 포인터 유형을 역참조해야 합니다 개체의 참조를 가져옵니다. 그런 다음 점(.) 연산자와 함께 사용하여 객체 멤버에 액세스할 수 있습니다.

그러나 이를 수행하는 더 좋은 방법은 짧고 깔끔한 화살표(->) 연산자를 사용하는 것입니다.

C++의 화살표(->) 연산자에 대한 자세한 내용은 문서를 참조하세요.

결론

이 기사에서는 C++의 expression must have class type 오류에 대해 설명했습니다. 이 오류가 발생하는 이유와 이를 해결하기 위한 다양한 솔루션에 대해 논의했습니다.

관련 문장 - C++ Error