> 백엔드 개발 > C++ > 본문

C++ 컴파일 오류: 휘발성 유형에서 변환된 멤버 함수를 호출할 수 없습니다. 어떻게 처리합니까?

PHPz
풀어 주다: 2023-08-21 21:28:55
원래의
899명이 탐색했습니다.

C++는 변수의 유형 변환을 엄격하게 제한하는 강력한 유형의 언어입니다. 그러나 경우에 따라 휘발성 유형 객체에 대해 유형 변환을 수행해야 할 수도 있습니다. 특히 임베디드 개발에서는 이러한 레지스터에 액세스해야 하는 경우가 많습니다. 일반적으로 휘발성 유형입니다. 그러나 휘발성 유형 개체에는 특별한 의미가 있기 때문에 C++ 컴파일러는 이에 대해 몇 가지 특별한 제한을 적용하며, 이로 인해 "휘발성 유형에서 변환된 멤버 함수를 호출할 수 없습니다"라는 오류가 발생합니다. 이 글에서는 이 오류의 원인과 해결 방법에 대해 설명합니다.

먼저 휘발성 유형의 의미를 살펴보겠습니다. C++에서 휘발성 키워드의 역할은 이 변수의 값이 프로그램 외부에서 수정될 수 있으므로 컴파일러가 이를 최적화할 수 없으며 해당 값이 액세스될 때마다 다시 읽혀지도록 컴파일러에 알리는 것입니다. 특히 휘발성 개체에는 다음과 같은 특징이 있습니다.

  • 휘발성 개체의 값은 하드웨어 인터럽트, 멀티스레딩 등과 같이 프로그램 외부에서 수정될 수 있습니다.
  • 휘발성 개체에 액세스할 때마다 해당 값을 다시 읽어야 하며 레지스터에 캐시된 값을 직접 사용할 수 없습니다.
  • 휘발성 개체에 대한 액세스는 순서를 바꾸거나 최적화할 수 없으며 프로그램의 순서대로 수행되어야 합니다.

이 의미론에 따라 휘발성 유형 객체를 사용하여 하드웨어 레지스터를 나타낼 수 있습니다. 휘발성 유형 객체는 비휘발성 유형 객체로 변환될 수 없습니다. 왜냐하면 이로 인해 특수 의미론이 파괴되기 때문입니다. 예를 들어, 다음 코드는 잘못되었습니다.

int x = 0;
volatile int &y = x;   // 复制x的地址,但y是volatile类型

x = 1;  // OK,修改x的值
y = 2;  // OK,修改x的值,但要重新读取其值
int z = y;  // 错误,不能读取volatile对象的值
int &u = y;  // 错误,不能将volatile类型的引用转换为非volatile类型
로그인 후 복사

위 코드에서는 비휘발성 변수 x를 휘발성 참조 y로 변환하려고 시도했는데 이는 잘못된 것입니다. 이렇게 하면 y를 통해 x 값을 수정할 수 있고 수정할 때마다 해당 값을 다시 읽을 수 있지만 휘발성 유형의 의미를 위반하기 때문에 일반 정수처럼 y 값을 읽을 수 없습니다.

한 단계 더 나아가, 휘발성 유형의 개체에 대해 멤버 함수를 호출하는 더 복잡한 상황을 고려해 보겠습니다. 예를 들어, 객체의 멤버 함수를 휘발성 유형으로 선언하면 호출 시 해당 멤버 변수의 가시성을 보장할 수 있습니다. 그러나 C++ 컴파일러는 휘발성 유형에서 비휘발성 유형으로의 변환을 허용하지 않으므로 "휘발성 유형에서 변환된 멤버 함수를 호출할 수 없습니다."라는 컴파일 오류가 발생합니다. 예:

class MyClass {
public:
    volatile int x;
    volatile void func() { x = x + 1; }
};

int main() {
    MyClass obj;
    obj.func();  // 错误,不能从volatile类型转换为非volatile类型
    return 0;
}
로그인 후 복사

위 코드에서는 MyClass 클래스를 정의합니다. 여기서 x는 휘발성 유형의 정수이고 func()는 휘발성 유형의 멤버 함수입니다. 이는 x에 대해 자동 증가 작업을 수행한다는 의미입니다. main() 함수에서 MyClass 객체 obj를 생성하고 해당 멤버 함수 func()를 호출하려고 시도합니다. 그러나 이렇게 하면 "휘발성 유형에서 변환된 멤버 함수를 호출할 수 없습니다"라는 컴파일 오류가 발생합니다. C++에서 멤버 함수는 this 포인터 매개변수가 숨겨진 일반 함수로 취급되기 때문에 멤버 함수를 호출할 때 this 포인터를 비휘발성 유형에서 휘발성 유형으로 변환하는 것은 허용되지 않습니다.

그렇다면 이 컴파일 오류를 어떻게 처리해야 할까요? 이 문제를 해결하는 방법에는 두 가지가 있습니다. 첫 번째 방법은 컴파일러가 오류를 보고하지 않도록 멤버 함수의 매개 변수를 휘발성 유형으로 선언하는 것입니다. 예:

class MyClass {
public:
    volatile int x;
    void func(volatile MyClass *thisptr) { thisptr->x = thisptr->x + 1; }
};

int main() {
    MyClass obj;
    obj.func(&obj);  // OK,将this指针转换为volatile类型
    return 0;
}
로그인 후 복사

위 코드에서 func() 함수의 thisptr 매개변수를 휘발성 유형의 MyClass 포인터로 선언하여 이를 호출할 때 this 포인터를 비휘발성 유형에서 휘발성 유형. 이 접근 방식은 문제를 해결할 수 있지만 코드를 장황하게 만들어 일반적으로 사용되지 않습니다.

두 번째 방법은 유형 삭제 기술을 사용하여 멤버 함수의 this 포인터를 void 포인터로 변환하여 휘발성 유형에 대한 컴파일러의 제한을 우회할 수 있도록 하는 것입니다. 예:

class MyClass {
public:
    volatile int x;
    void func() {
        volatile void *vthis = static_cast<volatile void *>(this);
        volatile MyClass *vptr = static_cast<volatile MyClass *>(vthis);
        vptr->x = vptr->x + 1;
    }
};

int main() {
    MyClass obj;
    obj.func();  // OK,使用类型擦除将this指针转换为volatile类型
    return 0;
}
로그인 후 복사

위 코드에서는 static_cast를 사용하여 이 포인터를 먼저 void 포인터로 변환한 다음 휘발성 MyClass 포인터로 변환하여 휘발성 this 포인터를 얻을 수 있습니다. 이 접근 방식으로 문제를 해결할 수는 있지만 유형 삭제 기술을 사용하는 방법을 이해해야 하며 코드의 가독성과 유지 관리 가능성에 영향을 미칠 수 있습니다.

요약하자면 C++ 컴파일 오류 "휘발성 유형에서 변환된 멤버 함수를 호출할 수 없습니다."는 휘발성 유형에 대한 컴파일러의 특수 제한으로 인해 발생합니다. 이 컴파일 오류를 해결하기 위해 멤버 함수의 매개변수를 휘발성 유형으로 선언하거나 유형 삭제 기술을 사용하여 멤버 함수의 this 포인터를 void 포인터로 변환할 수 있습니다. 어떤 방법을 사용하든 휘발성 개체를 비휘발성 개체로 변환하거나 그 반대로 변환하여 잘못된 결과가 발생하는 것을 방지하려면 휘발성 유형의 의미에 주의를 기울여야 합니다.

위 내용은 C++ 컴파일 오류: 휘발성 유형에서 변환된 멤버 함수를 호출할 수 없습니다. 어떻게 처리합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!