{"id":112764,"date":"2026-10-09T07:00:00","date_gmt":"2026-10-09T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=112764"},"modified":"2026-10-11T16:03:57","modified_gmt":"2026-10-11T23:03:57","slug":"20261009-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20261009-00\/?p=112764\/","title":{"rendered":"One way of thinking about access specifiers in C++\/WinRT implementation types"},"content":{"rendered":"<p>In C++\/WinRT, Windows Runtime classes are exposed to the outside world through the projection, but internally they are represented by their implementation type. Since the outside world sees only the projection, implementation types are visible only to the module that produced them.<\/p>\n<p>This realization lets you reinterpret the C++ access specifiers for C++\/WinRT implementation types.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Declared on<br \/>\nimplementation as<\/th>\n<th>C# and C++\/CX<br \/>\nequivalent<\/th>\n<th>Accessible to<\/th>\n<\/tr>\n<tr>\n<td>implemented interface<\/td>\n<td><tt>public<\/tt><\/td>\n<td>Anyone<\/td>\n<\/tr>\n<tr>\n<td><tt>public<\/tt><\/td>\n<td><tt>internal<\/tt><\/td>\n<td>Code in the same module<\/td>\n<\/tr>\n<tr>\n<td><tt>protected<\/tt><\/td>\n<td><tt>protected<\/tt><\/td>\n<td>Code in derived classes<\/td>\n<\/tr>\n<tr>\n<td><tt>private<\/tt><\/td>\n<td><tt>private<\/tt><\/td>\n<td>Code in the same class<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In code:<\/p>\n<pre>struct Widget : winrt::implements&lt;Widget, IStringable&gt;\r\n{\r\npublic:\r\n    \/\/ This is a member of IStringable,\r\n    \/\/ so it is accessible to anyone.\r\n    winrt::hstring ToString();\r\n\r\n    \/\/ This does not implement any member from IStringable,\r\n    \/\/ so it is accessible to other code in the same module.\r\n    void Recolor(winrt::Windows::UI::Color newColor);\r\n\r\nprotected:\r\n    \/\/ Accessible to implementation classes that derive from Widget.\r\n    void Reverse();\r\n\r\nprivate:\r\n    \/\/ Accessible only to Widget itself.\r\n    void Reset();\r\n};\r\n<\/pre>\n<p>Note that if you are implementing a runtime class, then C++\/WinRT autogenerates a template for you that auto-declares all of the declared interfaces of that class.<\/p>\n<pre>\/\/ Widget.idl\r\n\r\nnamespace Contoso\r\n{\r\n    runtimeclass Widget : Windows.Foundation.IStringable\r\n    {\r\n        String Name{ get; };\r\n        void Toggle();\r\n    }\r\n}\r\n<\/pre>\n<p>The IDL compiler autogenerates an interface <code>IWidget<\/code> with a property <code>Name<\/code> and a method <code>Toggle()<\/code>.<\/p>\n<pre>\/\/ implementation\r\nnamespace winrt::Contoso\r\n{\r\n    struct Widget : <span style=\"border: solid 1px currentcolor;\">WidgetT&lt;Widget&gt;<\/span>\r\n    {\r\n        \u27e6 ... \u27e7\r\n    };\r\n}\r\n<\/pre>\n<p>The <code>WidgetT&lt;Widget&gt;<\/code> expands to <code>implements&lt;Widget, IWidget, Windows::Foundation::IStringable&gt;<\/code> because those are the interfaces declared by the IDL file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mapping them to concepts from C# and the now-defunct C++\/CX.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-112764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Mapping them to concepts from C# and the now-defunct C++\/CX.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=112764"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112764\/revisions"}],"predecessor-version":[{"id":112765,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112764\/revisions\/112765"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=112764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=112764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=112764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}