다음을 통해 공유


컴파일러 경고(수준 2) C4251

'type': 클래스 'type1'에는 'type2' 클래스의 클라이언트에서 사용할 dll 인터페이스가 있어야 합니다

설명

이 경고는 클래스가 __declspec(dllexport) 또는 __declspec(dllimport)(으)로 표시되고 클래스의 멤버이거나 기본 클래스 중 하나의 멤버인 비정적 데이터 멤버가 __declspec(dllexport) 또는 __declspec(dllimport)(으)로 표시되지 않은 클래스 형식을 형식으로 가질 경우 발생합니다. 예제를 참조하세요.

__declspec(dllexport)(으)로 선언된 클래스를 내보낼 때 데이터 손상 가능성을 최소화하려면 다음을 확인합니다.

  • 모든 정적 데이터는 DLL에서 내보낸 함수를 통해 액세스됩니다.
  • 클래스의 인라인 메서드는 정적 데이터를 수정할 수 없습니다.
  • 클래스의 인라인 메서드는 정적 데이터를 사용하는 CRT 함수 또는 기타 라이브러리 함수를 사용하지 않습니다. 자세한 내용은 DLL 경계를 넘어 CRT 개체를 전달하는 잠재적 오류를 참조하세요.
  • 클래스의 메서드(인라인 여부)는 EXE 및 DLL의 인스턴스화에 정적 데이터 차이가 있는 형식을 사용할 수 없습니다.

다음을 통해 DLL에서 클래스를 내보낼 때 발생하는 이슈를 방지할 수 있습니다.

  • 가상 함수를 사용하도록 클래스를 정의합니다.
  • 가상 소멸자를 정의합니다.
  • 형식의 인스턴스를 인스턴스화하고 삭제하는 함수를 정의합니다.

클래스가 C++ 표준 라이브러리의 형식에서 파생되고 디버그 릴리스(/MTd)를 컴파일하는 경우 C4251을 무시할 수 있으며 컴파일러 오류 메시지가 _Container_base(을)를 참조합니다.

클래스에 __declspec(dllexport) 또는 __declspec(dllimport)(을)를 추가하는 것은 대부분 올바른 선택이 아니며 구현 세부 정보를 변경하는 것이 더 어려워지므로 유지 관리가 더 힘들어질 수 있으므로 신중하게 고려해야 합니다.

예시

// C4251.cpp
// Compile with /std:c++20 /EHsc /W2 /c C4251.cpp
#include <vector>
 
class __declspec(dllexport) X
{
public:
    X();
    ~X();
 
    void do_something();
 
private:
    void do_something_else();
    std::vector<int> data; // warning c4251
};

이 경고를 해결하려면 클래스를 __declspec(dllexport) 또는 __declspec(dllimport)(으)로 표시하지 마세요. 대신 클라이언트에서 직접 사용하는 메서드만 표시합니다. 예시:

// C4251_fixed.cpp
// Compile with /std:c++20 /EHsc /W2 /c C4251-fixed.cpp
#include <vector>
 
class X
{
public:
    __declspec(dllexport) X();
    __declspec(dllexport) ~X();
 
    __declspec(dllexport) void do_something();
 
private:
    void do_something_else();
    std::vector<int> data;
};