Ref 클래스 및 구조체(C++/CX)Ref classes and structs (C++/CX)

C + +/CX에서는 사용자 정의 ref 클래스ref 구조체와 사용자 정의 값 클래스값 구조체를 지원 합니다.The C++/CX supports user-defined ref classes and ref structs, and user-defined value classes and value structs. 이러한 데이터 구조는 c + +/CX에서 Windows 런타임 형식 시스템을 지 원하는 기본 컨테이너입니다.These data structures are the primary containers by which C++/CX supports the Windows Runtime type system. 해당 콘텐츠는 특정 규칙에 따라 메타 데이터로 내보내지고,이를 통해 Windows 런타임 구성 요소와 c + + 또는 다른 언어로 작성 된 유니버설 Windows 플랫폼 앱 간에 전달 될 수 있습니다.Their contents are emitted to metadata according to certain specific rules, and this enables them to be passed between Windows Runtime components and Universal Windows Platform apps that are written in C++ or other languages.

ref 클래스 또는 ref 구조체에는 다음과 같은 중요한 기능이 있습니다.A ref class or ref struct has these essential features:

  • 네임스페이스 안에서 선언되어야 하며, 네임스페이스 범위에 있어야 하며, 해당 네임스페이스에서 public 또는 private 액세스 가능성이 있을 수 있습니다.It must be declared within a namespace, at namespace scope, and in that namespace it may have public or private accessibility. public 형식만 메타데이터로 내보내집니다.Only public types are emitted to metadata. 중첩된 public enum 클래스를 포함하여 중첩된 public 클래스 정의는 허용되지 않습니다.Nested public class definitions are not permitted, including nested public enum classes. 자세한 내용은 네임 스페이스 및 형식 표시유형을 참조 하세요.For more information, see Namespaces and Type Visibility.

  • Ref 클래스, 값 클래스, ref 구조체, 값 구조체 또는 nullable 값 구조체를 포함 하는 c + +/CX를 멤버로 포함할 수 있습니다.It may contain as members C++/CX including ref classes, value classes, ref structs, value structs, or nullable value structs. 또한, 등의 스칼라 형식도 포함할 수 float64 있습니다 bool .It may also contain scalar types such as float64, bool, and so on. 또한 std::vector 또는 사용자 지정 클래스(public이 아니어야 함)와 같은 표준 C++ 형식을 포함할 수 있습니다.It may also contain standard C++ types such as std::vector or a custom class, as long as they are not public. C + +/cx 구문에는 public ,, protected internal , private 또는 protected private 액세스 가능성이 있을 수 있습니다.C++/CX constructs may have public, protected, internal, private, or protected private accessibility. 모든 public 또는 protected 멤버는 메타 데이터로 내보내집니다.All public or protected members are emitted to metadata. 표준 c + + 형식에는 private internal protected private 메타 데이터로 내보내지 못하도록 하는, 또는 액세스 가능성이 있어야 합니다.Standard C++ types must have private, internal, or protected private accessibility, which prevents them from being emitted to metadata.

  • 하나 이상의 인터페이스 클래스 또는 인터페이스 구조체를 구현할 수 있습니다.It may implement one or more interface classes or interface structs.

  • 한 기본 클래스에서 상속할 수 있으며 기본 클래스 자체에는 추가 제한이 있습니다.It may inherit from one base class, and base classes themselves have additional restrictions. public ref 클래스 계층 구조의 상속에는 private ref 클래스의 상속보다 많은 제한이 있습니다.Inheritance in public ref class hierarchies has more restrictions than inheritance in private ref classes.

  • 제네릭으로 선언될 수 없습니다.It may not be declared as generic. private 액세스 가능성이 있는 경우 템플릿일 수 있습니다.If it has private accessibility, it may be a template.

  • 수명은 참조 횟수를 자동으로 계산하여 관리됩니다.Its lifetime is managed by automatic reference counting.

선언Declaration

다음 코드 조각에서는 Person ref 클래스를 선언합니다.The following code fragment declares the Person ref class. Private 멤버에는 표준 c + + std::map 형식이 사용 되 고, IMapView 공용 인터페이스에는 Windows 런타임 인터페이스가 사용 됩니다.Notice that the standard C++ std::map type is used in the private members, and the Windows RuntimeIMapView interface is used in the public interface. 또한 참조 형식 선언에 "^"가 추가되었습니다.Also notice that the "^" is appended to declarations of reference types.

// #include <map>
namespace WFC = Windows::Foundation::Collections;
namespace WFM = Windows::Foundation::Metadata;

[WFM::WebHostHidden]
ref class Person sealed
{
public:
    Person(Platform::String^ name);
    void AddPhoneNumber(Platform::String^ type, Platform::String^ number);
    property WFC::IMapView<Platform::String^, Platform::String^>^ PhoneNumbers
    { 
        WFC::IMapView<Platform::String^, Platform::String^>^ get();
    }
private:
    Platform::String^ m_name;
    std::map<Platform::String^, Platform::String^> m_numbers;
};

구현Implementation

이 코드 예제에서는 Person ref 클래스의 구현을 보여 줍니다.This code example shows an implementation of the Person ref class:

#include <collection.h>
using namespace Windows::Foundation::Collections;
using namespace Platform;
using namespace Platform::Collections;

Person::Person(String^ name): m_name(name) { }
void Person::AddPhoneNumber(String^ type, String^ number)
{
    m_numbers[type] = number;
}
IMapView< String^, String^>^ Person::PhoneNumbers::get()
{
    // Simple implementation. 
    return ref new MapView< String^, String^>(m_numbers);
}

사용Usage

다음 코드 예제에서는 클라이언트 코드가 Person ref 클래스를 사용하는 방법을 보여 줍니다.The next code example shows how client code uses the Person ref class.

using namespace Platform;

Person^ p = ref new Person("Clark Kent");
p->AddPhoneNumber("Home", "425-555-4567");
p->AddPhoneNumber("Work", "206-555-9999");
String^ workphone = p->PhoneNumbers->Lookup("Work");

또한 스택 의미 체계를 사용하여 지역 ref 클래스 변수를 선언할 수도 있습니다.You can also use stack semantics to declare a local ref class variable. 이러한 개체는 메모리가 계속 동적으로 할당되는 경우에도 스택 기반 변수처럼 동작합니다.Such an object behaves like a stack-based variable even though the memory is still allocated dynamically. 중요한 차이점은 스택 의미 체계로 선언된 변수에는 함수가 종료되면 참조 횟수가 0으로 감소하도록 보장하는 추적 참조(%)를 할당할 수 없다는 점입니다.One important difference is that you cannot assign a tracking reference (%) to a variable that is declared by using stack semantics; this guarantees that the reference count is decremented to zero when the function exits. 이 예제에서는 기본 ref 클래스 Uri및 스택 의미 체계에 이를 사용하는 함수를 보여 줍니다.This example shows a basic ref class Uri, and a function that uses it with stack semantics:

void DoSomething()
{
    Windows::Foundation::Uri docs("http://docs.microsoft.com");
    Windows::Foundation::Uri^ devCenter = docs.CombineUri("/windows/");
    // ... 
} // both variables cleaned up here.

메모리 관리Memory management

키워드를 사용 하 여 동적 메모리에 ref 클래스를 할당 ref new 합니다.You allocate a ref class in dynamic memory by using the ref new keyword.

MyRefClass^ myClass = ref new MyRefClass();

개체 핸들 연산자는 ^ hat 이라고 하며 근본적으로 c + + 스마트 포인터입니다.The handle-to-object operator ^ is known as a hat and is fundamentally a C++ smart pointer. 이 포인터가 가리키는 메모리는 마지막 hat가 범위를 벗어나거나 명시적으로로 설정 된 경우 자동으로 제거 됩니다 nullptr .The memory it points to is automatically destroyed when the last hat goes out of scope or is explicitly set to nullptr.

정의에 따라 ref 클래스에는 참조 의미 체계가 있습니다.By definition, a ref class has reference semantics. ref 클래스 변수를 할당할 경우 이는 개체 자체가 아니라 복사된 핸들입니다.When you assign a ref class variable, it's the handle that's copied, not the object itself. 다음 예제에서 할당 후 myClassmyClass2 는 동일한 메모리 위치를 가리킵니다.In the next example, after assignment, both myClass and myClass2 point to the same memory location.

MyRefClass^ myClass = ref new MyRefClass();
MyRefClass^ myClass2 = myClass;

C++/CX ref 클래스가 인스턴스화되면 생성자가 호출되기 전에 메모리가 0으로 초기화되므로 속성을 포함한 개별 멤버를 0으로 초기화할 필요가 없습니다.When a C++/CX ref class is instantiated, its memory is zero-initialized before its constructor is called; therefore it is not necessary to zero-initialize individual members, including properties. C++/CX 클래스가 WRL(Windows 런타임 C++ 라이브러리) 클래스에서 파생되는 경우 C++/CX 파생 클래스 부분만 0으로 초기화됩니다.If the C++/CX class derives from a Windows Runtime C++ Library (WRL) class, only the C++/CX derived class portion is zero-initialized.

멤버Members

Ref 클래스에는, 및 함수 멤버가 포함 될 수 있습니다. public protected private publicprotected 멤버만 메타 데이터로 내보내집니다.A ref class can contain public, protected, and private function members; only public and protected members are emitted into metadata. 중첩 클래스 및 ref 클래스는 허용 되지만 일 수 없습니다 public .Nested classes and ref classes are permitted but cannot be public. public 필드는 허용되지 않습니다. public 데이터 멤버는 속성으로 선언되어야 합니다.Public fields are not allowed; public data members must be declared as properties. private 또는 protected internal 데이터 멤버는 필드가 될 수 있습니다.Private or protected internal data members may be fields. 기본적으로 ref 클래스에서 모든 멤버의 액세스 가능성은 private 입니다.By default in a ref class, the accessibility of all members is private.

Ref 구조체는 기본적으로 멤버의 액세스 가능성이 있는 경우를 제외 하 고 ref 클래스와 동일 합니다 public .A ref struct is the same as a ref class, except that by default its members have public accessibility.

public Ref 클래스 또는 ref 구조체는 메타 데이터로 내보내지고 다른 유니버설 Windows 플랫폼 앱 및 Windows 런타임 구성 요소에서 사용할 수 있도록 하려면 public 또는 protected 생성자가 하나 이상 있어야 합니다.A public ref class or ref struct is emitted in metadata, but to be usable from other Universal Windows Platform apps and Windows Runtime components it must have at least one public or protected constructor. sealed ABI (응용 프로그램 이진 인터페이스)를 통한 추가 파생을 방지 하려면 public 생성자가 있는 public ref 클래스도로 선언 되어야 합니다.A public ref class that has a public constructor must also be declared as sealed to prevent further derivation through the application binary interface (ABI).

const Windows 런타임 형식 시스템에서 const를 지원 하지 않으므로 공용 멤버를로 선언할 수 없습니다.Public members may not be declared as const because the Windows Runtime type system does not support const. 정적 속성을 사용하여 상수 값으로 public 데이터 멤버를 선언할 수 있습니다.You can use a static property to declare a public data member with a constant value.

public ref 클래스 또는 구조체를 정의하는 경우 컴파일러가 클래스에 필수 특성을 적용하고 해당 정보를 응용 프로그램의 .winmd 파일에 저장합니다.When you define a public ref class or struct, the compiler applies the required attributes to the class and stores that information in the .winmd file of the app. 그러나 봉인 되지 않은 public ref 클래스를 정의 하는 경우 클래스를 Windows::Foundation::Metadata::WebHostHidden JavaScript로 작성 된 유니버설 Windows 플랫폼 앱에 표시 하지 않도록 특성을 수동으로 적용 합니다.However, when you define a public unsealed ref class, manually apply the Windows::Foundation::Metadata::WebHostHidden attribute to ensure that the class is not visible to Universal Windows Platform apps that are written in JavaScript.

Ref 클래스는, const 또는 멤버에 형식을 포함 한 표준 c + + 형식을 포함할 수 있습니다 private internal protected private .A ref class can have standard C++ types, including const types, in any private, internal, or protected private members.

형식 매개 변수가 있는 public ref 클래스는 허용되지 않습니다.Public ref classes that have type parameters are not permitted. 사용자 정의 제네릭 ref 클래스는 허용되지 않습니다.User-defined generic ref classes are not permitted. private, internal 또는 protected private ref 클래스는 템플릿일 수 있습니다.A private, internal, or protected private ref class may be a template.

소멸자Destructors

C + +/CX에서 delete public 소멸자를 호출 하면 개체의 참조 횟수에 관계 없이 소멸자가 호출 됩니다.In C++/CX, calling delete on a public destructor invokes the destructor regardless of the object's reference count. 이 동작을 통해 명확한 방식으로 비 RAII 리소스의 사용자 지정 정리를 수행하는 소멸자를 정의할 수 있습니다.This behavior enables you to define a destructor that performs custom cleanup of non-RAII resources in a deterministic manner. 그러나 이 경우에도 개체 자체는 메모리에서 삭제되지 않습니다.However, even in this case, the object itself is not deleted from memory. 참조 횟수가 0에 도달할 때만 개체에 대한 메모리가 확보됩니다.The memory for the object is only freed when the reference count reaches zero.

클래스의 소멸자가 public이 아닌 경우에는 참조 횟수가 0에 도달할 때만 소멸자가 호출됩니다.If a class's destructor is not public, then it is only invoked when the reference count reaches zero. deletePrivate 소멸자가 있는 개체에 대해를 호출 하는 경우 컴파일러는 경고 4493를 발생 시킵니다 .이는의 소멸자에 <type name> ' public ' 액세스 가능성이 없으므로 "delete 식이 영향을 주지 않습니다." 라는 메시지를 표시 합니다.If you call delete on an object that has a private destructor, the compiler raises warning C4493, which says "delete expression has no effect as the destructor of <type name> does not have 'public' accessibility."

ref 클래스 소멸자는 다음과 같이 선언될 수만 있습니다.Ref class destructors can only be declared as follows:

  • public 및 virtual(sealed 또는 unsealed 형식에서 허용됨)public and virtual (allowed on sealed or unsealed types)

  • protected private 및 비가상(unsealed 형식에서만 허용됨)protected private and non-virtual (only allowed on unsealed types)

  • private 및 비가상(sealed 형식에서만 허용됨)private and non-virtual (allowed only on sealed types)

액세스 가능성, 가상 및 봉인의 다른 조합은 허용되지 않습니다.No other combination of accessibility, virtualness, and sealedness is allowed. 소멸자를 명시적으로 선언하지 않으면 컴파일러가 형식의 기본 클래스 또는 멤버에 public 소멸자가 있는 경우 public virtual 소멸자를 생성하고,If you do not explicitly declare a destructor, the compiler generates a public virtual destructor if the type's base class or any member has a public destructor. 그렇지 않으면 unsealed 형식의 경우 비가상 protected private 소멸자를 생성하고 sealed 형식의 경우 비가상 private 소멸자를 생성합니다.Otherwise, the compiler generates a protected private non-virtual destructor for unsealed types, or a private non-virtual destructor for sealed types.

이미 소멸자가 실행되도록 한 클래스의 멤버에 액세스하려고 하는 경우의 동작은 정의되어 있지 않습니다. 프로그램 작동이 중단될 가능성이 놓습니다.The behavior is undefined if you try to access members of a class that has already had its destructor run; it will most likely cause the program to crash. public 소멸자가 없는 형식에 대해 delete t 를 호출하면 아무런 효과가 없습니다.Calling delete t on a type that has no public destructor has no effect. 형식 delete this 계층 구조 내에서 알려진 또는 소멸자가 있는 형식 또는 기본 클래스에 대해를 호출 private protected private 해도 아무런 효과가 없습니다.Calling delete this on a type or base class that has a known private or protected private destructor from within its type hierarchy also has no effect.

public 소멸자를 선언하는 경우 ref 클래스가 Platform::IDisposable 을 구현하고 소멸자가 Dispose 메서드를 구현하도록 컴파일러에서 코드가 생성됩니다.When you declare a public destructor, the compiler generates the code so that the ref class implements Platform::IDisposable and the destructor implements the Dispose method. Platform::IDisposable는의 c + +/CX 프로젝션입니다 Windows::Foundation::IClosable .Platform::IDisposable is the C++/CX projection of Windows::Foundation::IClosable. 이러한 인터페이스를 명시적으로 구현하지 마세요.Never explicitly implement these interfaces.

상속Inheritance

Platform::Object는 모든 ref 클래스의 유니버설 기본 클래스입니다.Platform::Object is the universal base class for all ref classes. 모든 ref 클래스는 암시적으로 Platform::Object로 변환될 수 있으며 Object::ToString을 재정의할 수 있습니다.All ref classes are implicitly convertible to Platform::Object and can override Object::ToString. 그러나 Windows 런타임 상속 모델은 일반 상속 모델로 사용할 수 없습니다. c + +/CX에서는 사용자 정의 public ref 클래스를 기본 클래스로 사용할 수 없습니다.However, the Windows Runtime inheritance model not intended as a general inheritance model; in C++/CX this means that a user-defined public ref class cannot serve as a base class.

XAML 사용자 정의 컨트롤을 만들며 개체가 종속성 속성 시스템에 참여하는 경우에는 Windows::UI::Xaml::DependencyObject 를 기본 클래스로 사용할 수 있습니다.If you are creating a XAML user control, and the object participates in the dependency property system, then you can use Windows::UI::Xaml::DependencyObject as a base class.

MyBase 에서 상속하는 unsealed 클래스 DependencyObject를 정의한 후 구성 요소나 응용 프로그램의 다른 public 또는 private ref 클래스가 MyBase에서 상속할 수 있습니다.After you have defined an unsealed class MyBase that inherits from DependencyObject, other public or private ref classes in your component or app may inherit from MyBase. public ref 클래스의 상속은 가상 메서드의 재정의, 다형 ID 및 캡슐화를 지원하기 위해서만 수행되어야 합니다.Inheritance in public ref classes should only be done to support overrides of virtual methods, polymorphic identity, and encapsulation.

기본 private ref 클래스는 기존 unsealed 클래스에서 파생하는 데 필요하지 않습니다.A private base ref class is not required to derive from an existing unsealed class. 자체 프로그래밍 구조를 모델링하거나 코드 재사용을 가능하게 하기 위해 개체 계층 구조가 필요한 경우 private 또는 internal ref 클래스를 사용하거나 표준 C++ 클래스를 사용하세요.If you require an object hierarchy to model your own program structure or to enable code reuse, then use private or internal ref classes, or better yet, standard C++ classes. public sealed ref 클래스 래퍼를 통해 private 개체 계층 구조의 기능을 노출할 수 있습니다.You can expose the functionality of the private object hierarchy through a public sealed ref class wrapper.

C + +/CX에서 public 또는 protected 생성자가 있는 ref 클래스는 sealed로 선언 되어야 합니다.A ref class that has a public or protected constructor in C++/CX must be declared as sealed. 이러한 제한 사항은 c # 또는 Visual Basic 같은 다른 언어로 작성 된 클래스에 c + +로 작성 된 Windows 런타임 구성 요소에서 선언 하는 형식에서 상속 하는 방법이 없음을 의미 합니다.This restriction means that there is no way for classes that are written in other languages such as C# or Visual Basic to inherit from types that you declare in a Windows Runtime component that's written in C++/CX.

C + +/CX의 상속에 대 한 기본 규칙은 다음과 같습니다.Here are the basic rules for inheritance in C++/CX:

  • ref 클래스가 직접 상속할 수 있는 기본 ref 클래스는 하나뿐이지만 구현할 수 있는 인터페이스의 개수에는 제한이 없습니다.Ref classes can inherit directly from at most one base ref class, but can implement any number of interfaces.

  • public 생성자가 있는 클래스는 추가 파생을 방지하기 위해 sealed로 선언되어야 합니다.If a class has a public constructor, it must be declared as sealed to prevent further derivation.

  • internal 또는 protected private 생성자가 있는 public unsealed 기본 클래스를 만들 수 있습니다. 단, 해당 기본 클래스가 Windows::UI::Xaml::DependencyObject와 같은 기존 unsealed 기본 클래스에서 직접 또는 간접적으로 파생되는 경우에 한합니다.You can create public unsealed base classes that have internal or protected private constructors, provided that the base class derives directly or indirectly from an existing unsealed base class such as Windows::UI::Xaml::DependencyObject. .winmd 파일 전반에서 사용자 정의 ref 클래스의 상속은 지원되지 않지만 ref 클래스는 다른 .winmd 파일에서 정의된 인터페이스에서 상속할 수 있습니다.Inheritance of user-defined ref classes across .winmd files is not supported; however, a ref class can inherit from an interface that's defined in another .winmd file. 사용자 정의 기본 ref 클래스에서 파생 클래스는 동일한 Windows 런타임 구성 요소나 유니버설 Windows 플랫폼 앱 내 에서만 만들 수 있습니다.You can create derived classes from a user-defined base ref class only within the same Windows Runtime component or Universal Windows Platform app.

  • ref 클래스의 경우 공용 상속만 지원됩니다.For ref classes, only public inheritance is supported.

    ref class C{};
    public ref class D : private C //Error C3628
    {};
    

다음 예제에서는 상속 계층 구조의 다른 ref 클래스에서 파생되는 public ref 클래스를 노출하는 방법을 보여 줍니다.The following example shows how to expose a public ref class that derives from other ref classes in an inheritance hierarchy.

namespace InheritanceTest2 
{
    namespace WFM = Windows::Foundation::Metadata;

    // Base class. No public constructor.
    [WFM::WebHostHidden]
    public ref class Base : Windows::UI::Xaml::DependencyObject
    {
    internal:
        Base(){}
    protected:
        virtual void DoSomething (){}
        property Windows::UI::Xaml::DependencyProperty^ WidthProperty;
    };

    // Class intended for use by client code across ABI.
    // Declared as sealed with public constructor.
    public ref class MyPublicClass sealed : Base
    {
    public:
        MyPublicClass(){}
        //...
    };
}

참고 항목See also

유형 시스템Type System
값 클래스 및 구조체Value classes and structs
C + +/CX 언어 참조C++/CX Language Reference
네임 스페이스 참조Namespaces Reference