{"id":603,"date":"2017-06-20T01:00:22","date_gmt":"2017-06-20T01:00:22","guid":{"rendered":"https:\/\/www.fluentcpp.com\/?p=603"},"modified":"2017-09-18T07:08:05","modified_gmt":"2017-09-18T07:08:05","slug":"interface-principle-cpp","status":"publish","type":"post","link":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/","title":{"rendered":"The Interface Principle in C++"},"content":{"rendered":"<p><a href=\"https:\/\/www.fluentcpp.com\/dailycpp\"><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-1947 size-full\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png?resize=120%2C116&#038;ssl=1\" alt=\"Daily C++\" width=\"120\" height=\"116\" \/><\/a><\/p>\n<p>The Interface Principle in C++\u00a0encompasses\u00a0a specific combination of features and ways of considering what\u00a0an interface is, that allows to write expressive C++ code that preserves encapsulation. It has been around for a while, is still currently used, and may\u00a0be enriched in the future versions of the language. So it&#8217;s worth being aware of.<\/p>\n<p>Note that the Interface Principle goes beyond\u00a0the general concept of\u00a0having interfaces, and is not directly related to polymorphism.<\/p>\n<p>The convention we will use throughout this article is this:<\/p>\n<ul>\n<li>a <strong>method<\/strong>\u00a0designates a routine that is a member of a class,<\/li>\n<li>a <strong>(free) function<\/strong> is a routine\u00a0that is not part of a class.<\/li>\n<\/ul>\n<h3><span style=\"color: #ff6600;\">Non-member (non-friend) functions<\/span><\/h3>\n<p>In Item 23 of <a href=\"https:\/\/www.amazon.com\/gp\/product\/0321334876\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321334876&amp;linkCode=as2&amp;tag=fluentcpp-20&amp;linkId=c827183fcb052e6a805d39ee7d66095\" target=\"_blank\" rel=\"noopener\">Effective C++<\/a>, Scott Meyers encourages us to pull\u00a0methods of a given class <em>outside<\/em> of the class, whenever it is possible to implement them in terms of the public interface of the class (or with other methods that have been taken out of the class).<\/p>\n<p>To illustrate this let&#8217;s consider the\u00a0<code>Circle<\/code>\u00a0class that provides its radius, area and perimeter:<\/p>\n<pre class=\"lang:c++ decode:true\">class Circle\r\n{\r\npublic:\r\n    explicit Circle(double radius) : m_radius(radius) {}\r\n\r\n    double getRadius() const {return m_radius;}\r\n    double getPerimeter() const {return 2 * Pi * m_radius;}\r\n    double getArea() const {return Pi * m_radius * m_radius;}\r\n\r\nprivate:\r\n    double m_radius;\r\n};<\/pre>\n<p>A first improvement would be to use the public interface inside the implementation of the methods:<\/p>\n<pre class=\"lang:c++ decode:true\">    double getPerimeter() const {return 2 * Pi * getRadius();}\r\n    double getArea() const {return Pi * getRadius() * getRadius();}\r\n<\/pre>\n<p>And then these methods can be taken out of the class. Indeed they don&#8217;t need to be class methods, because they don&#8217;t use anything a external function couldn&#8217;t use. Taking them out of the class and making them free functions guarantees that\u00a0this characteristic of not using anything else than the public interface will be preserved, and therefore contributes to the encapsulation of the insides of the <code>Circle<\/code>\u00a0class.<\/p>\n<pre class=\"lang:c++ decode:true\">class Circle\r\n{\r\npublic:\r\n    explicit Circle(double radius) : m_radius(radius) {}\r\n\r\n    double getRadius() const {return m_radius;}\r\n\r\nprivate:\r\n    double m_radius;\r\n};\r\n\r\ndouble getPerimeter(Circle const&amp; circle) {return 2 * Pi * circle.getRadius();}\r\ndouble getArea(Circle const&amp; circle) {return Pi * circle.getRadius() * circle.getRadius();}<\/pre>\n<p>Another way to see this is that this\u00a0decreased the amount of code that could be impacted by a change in the implementation of the class <code>Circle<\/code>, therefore making the code a bit more robust to future change.<\/p>\n<p>If you want a way to reproduce this consistently, here is the methodology we applied:<\/p>\n<ul>\n<li>check that the implementation of a given methods only depends on the public interface (or make it so if it&#8217;s not too much hassle),<\/li>\n<li>create a free function with the <strong>same name<\/strong> as the method,<\/li>\n<li>add the type of the class as <strong>first parameter<\/strong>:\n<ul>\n<li>pass it by reference if the methods was not const<\/li>\n<li>pass it by reference-to-const if the method was const<\/li>\n<\/ul>\n<\/li>\n<li>paste the implementation, adding the object name before each\u00a0call to the class public interface.<\/li>\n<\/ul>\n<p><span style=\"line-height: 1.5;\">It\u00a0is important to note that the new free function should have the <strong>same name<\/strong> as the old method. Sometimes we are reluctant to call a free function <\/span><code style=\"line-height: 1.5;\">getPerimeter<\/code><span style=\"line-height: 1.5;\">. We would be more inclined to call it something like\u00a0<\/span><code style=\"line-height: 1.5;\">getCirclePerimeter<\/code><span style=\"line-height: 1.5;\">. Indeed, since\u00a0it is not enclosed in the <\/span><code style=\"line-height: 1.5;\">Circle<\/code><span style=\"line-height: 1.5;\">\u00a0class, we may feel it is ambiguous to omit the term &#8220;Circle&#8221;. But this is wrong: the term &#8220;Circle&#8221; already appears in the type of the first argument. Therefore it is reasonably expressive both for a human and a compiler to omit the type name in the function name.<\/span><\/p>\n<p>Actually, including the argument type in the function name\u00a0would even lead to\u00a0code looking slightly weird:<\/p>\n<pre class=\"lang:c++ decode:true \">getCirclePerimeter(circle); \/\/ \"Circle\" mentioned twice<\/pre>\n<p>as opposed to:<\/p>\n<pre class=\"lang:c++ decode:true\">getPerimeter(circle);<\/pre>\n<p>which reads more naturally. Also, the fact that the argument type is a <code>Circle<\/code>\u00a0makes it unambiguous for the compiler that this is the function you mean to call, even if there are other overloads sharing the name\u00a0<code>getPerimeter<\/code>.<\/p>\n<h3><span style=\"color: #ff6600;\">The Interface Principle<\/span><\/h3>\n<p>The new version of the class <code>Circle<\/code>\u00a0has something that may seem\u00a0disturbing: it has functionality declared outside of its interface. That was the purpose of making methods non-members in the first place, but normally a class should expose its responsibilities within its &#8220;public:&#8221; section, right?<\/p>\n<p>True, a class should expose its responsibilities in its <em>interface<\/em>. But an interface can be defined\u00a0by something more general than just the public section of a class declaration. This is what the <strong>Interface Principle<\/strong> does. It is explained in great details in Herb Sutter&#8217;s <a href=\"https:\/\/www.amazon.com\/gp\/product\/0201615622\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0201615622&amp;linkCode=as2&amp;tag=fluentcpp-20&amp;linkId=78c6f12c2158816db968432bff066aab\" target=\"_blank\" rel=\"noopener\">Exceptional C++<\/a> from Item 31 to 34, but its definition is essentially this:<\/p>\n<p>A free function is part of a class interface if:<\/p>\n<ul>\n<li>it takes an object of the class type as a parameter,<\/li>\n<\/ul>\n<ul>\n<li>it is in the <strong>same namespace<\/strong> as the class,<\/li>\n<\/ul>\n<ul>\n<li>it is shipped with the class, meaning that it is declared in the <strong>same header<\/strong> as the class.<\/li>\n<\/ul>\n<p>This is the case for the <code>getPerimeter<\/code>\u00a0and <code>getArea<\/code>\u00a0functions (here they are in a global namespace, but the next section adds namespaces to precisely see how this interacts with the Interface Principle). Therefore if you declare a function taking an object of the class type as a parameter, declared in the same namespace and header as a class, then your are expressing that this function is conceptually part of the class interface.<\/p>\n<p>As a result, the only difference between a function and a method of the class interface becomes\u00a0its invocation syntax:<\/p>\n<pre class=\"lang:c++ decode:true \">getPerimeter(circle);<\/pre>\n<p>for the function, versus<\/p>\n<pre class=\"lang:c++ decode:true \">circle.getPerimeter();<\/pre>\n<p>for the\u00a0method. But beyond this difference, the Interface Principle implies\u00a0that these two syntaxes express the same thing: invoking the <code>getPerimeter<\/code> routine from the <code>Circle<\/code>\u00a0interface.<\/p>\n<p>This lets us take code away from the class to improve encapsulation, while still preserving\u00a0the semantics of the method.<\/p>\n<h3><span style=\"color: #ff6600;\">The ADL: the Interface Principle playing nice with namespaces<\/span><\/h3>\n<p>With solely\u00a0the above definition of the Interface Principle, there would be an issue with namespaces: calling non-member functions would have\u00a0a burden over calling methods, because it would need to add\u00a0the namespace to the invocation.<\/p>\n<p>To illustrate, let&#8217;s put the interface of\u00a0<code>Circle<\/code>\u00a0in a namespace, <code>geometry<\/code>:<\/p>\n<pre class=\"lang:c++ decode:true\">namespace geometry\r\n{\r\n\r\nclass Circle\r\n{\r\npublic:\r\n    explicit Circle(double radius) : m_radius(radius) {}\r\n\r\n    double getRadius() const {return m_radius;}\r\n\r\nprivate:\r\n    double m_radius;\r\n};\r\n\r\ndouble getPerimeter(Circle const&amp; circle) {return 2 * Pi * circle.getRadius();}\r\ndouble getArea(Circle const&amp; circle) {return Pi * m_radius * circle.getRadius();}\r\n\r\n} \/\/ end of namespace geometry<\/pre>\n<p>Then calling the function provided in the interface could be done the following way:<\/p>\n<pre class=\"lang:c++ decode:true\">geometry::getArea(circle);<\/pre>\n<p>Compare this to the call to method:<\/p>\n<pre class=\"lang:c++ decode:true\">circle.getArea();<\/pre>\n<p>This discrepancy is a problem, because the Interface Principle wants the method and the free function to be considered as \u00a0semantically equivalent. Therefore you shouldn&#8217;t have to provide any additional information when calling the free function form. And the problem gets bigger in the case of nested\u00a0namespaces.<\/p>\n<p>This is solved by the Argument Dependent Lookup (ADL), also called Koenig lookup.<\/p>\n<p>The ADL is a native C++ feature that brings <strong>all functions declared in the namespaces of the arguments\u00a0types of the call<\/strong> to the scope of the functions searched for resolving the call. In the above example, <code>circle<\/code>\u00a0being an object of the type <code>Circle<\/code>\u00a0in the namespace <code>geometry<\/code>, all free functions in this namespace are considered for resolving the function call. And this includes <code>getArea<\/code>. So you can write the following code:<\/p>\n<pre class=\"lang:c++ decode:true\">getArea(circle);<\/pre>\n<p>which therefore expresses just as much as what a human and a compiler need to understand what you mean.<\/p>\n<h3><span style=\"color: #ff6600;\">Generic code<\/span><\/h3>\n<p>On the top of encapsulation, free functions let you do more flexible things than methods in cases of generic code.<\/p>\n<p>We saw in the first section of this article that it was preferable to avoid adding the argument type in the function name, for code clarity. But having general names also makes it easier to create generic code. Imagine you had a class <code>Rectangle<\/code>\u00a0over which you can calculate a perimeter too:<\/p>\n<pre class=\"lang:c++ decode:true\">double getPerimeter(Rectangle const&amp; rectangle);<\/pre>\n<p>Then the <code>getPerimeter<\/code>\u00a0function can be used in generic code more easily than if it contained superfluous information about argument types in its name:<\/p>\n<pre class=\"lang:c++ decode:true\">template &lt;typename Shape&gt;\r\nvoid operateOnShape(Shape const&amp; shape)\r\n{\r\n    double perimeter = getPerimeter(shape);\r\n    ....\r\n}<\/pre>\n<p>Consider how much harder this would be to write such code with functions like\u00a0<code>getCirclePerimeter<\/code>\u00a0and <code>getRectanglePerimeter<\/code>.<\/p>\n<p>Also, there are types on which you cannot add methods, because they are native C++ types for example, or because it is code that for some reason you don&#8217;t have the possibility to change. Then\u00a0you can\u00a0define free functions that accept these types as argument.<\/p>\n<p>An example can be found in the STL with the <em>functions<\/em> (not methods) <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/iterator\/begin\" target=\"_blank\" rel=\"noopener\"><code>std::begin<\/code><\/a>\u00a0and <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/iterator\/end\" target=\"_blank\" rel=\"noopener\"><code>std::end<\/code><\/a>. These functions call the <code>begin<\/code>\u00a0and <code>end<\/code>\u00a0methods of their container arguments, and have a specific implementation for arrays (<code>T[]<\/code>), because arrays don&#8217;t have <code>begin<\/code>\u00a0and\u00a0<code>end<\/code>\u00a0methods. This lets you write generic code that can accept both containers and arrays indifferently.<\/p>\n<h3><span style=\"color: #ff6600;\">A uniform function call syntax in C++?<\/span><\/h3>\n<p>The language already has features that facilitate benefiting from the Interface Principle. The ADL is one of them. And there seems to be a trend\u00a0with new or future features to go in that direction.<\/p>\n<p><code>std::invoke<\/code>\u00a0allows to have exactly the same syntax for calling a function or a method. The following syntax:<\/p>\n<pre class=\"lang:c++ decode:true\">std::invoke(f, x, x1, ..., xn);\r\n<\/pre>\n<ul>\n<li>calls <code>f(x, x1, ..., xn)<\/code> if f is not a class method,<\/li>\n<li>calls <code>x.f(x1, ..., xn)<\/code> if f is a class method.<\/li>\n<\/ul>\n<p><code>std::invoke<\/code>\u00a0becomes available in C++17.<\/p>\n<p>Finally, there have been discussions around the\u00a0proposal to implement\u00a0this equivalence natively in the language, so that<\/p>\n<pre class=\"lang:c++ decode:true \">f(x, x1, ..., xn);<\/pre>\n<p>calls <code>x.f(x1, ..., xn)<\/code>\u00a0if f is not a function but a method, and<\/p>\n<pre class=\"lang:c++ decode:true \">x.f(x1, ..., xn);<\/pre>\n<p>calls <code>f(x, x1, ..., xn)<\/code>\u00a0if f is a not method but a free function.\u00a0This is called the\u00a0Unified Call Syntax, here is a <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2015\/n4474.pdf\" target=\"_blank\" rel=\"noopener\">description<\/a> of it by Bjarne Stroustrup and Herb Sutter.<\/p>\n<p>I don&#8217;t know if this particular proposal will make it to\u00a0the standard one day, but one thing is sure: the language has been evolving and continues to evolve in that direction. Keeping this in mind when designing code makes it more natural, more robust, and more expressive.<\/p>\n<p>Related articles:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.fluentcpp.com\/2017\/01\/30\/how-to-choose-good-names\/\">How to choose good names for your code<\/a><\/li>\n<\/ul>\nDon't want to miss out ? <strong>Follow:<\/strong> &nbsp&nbsp<a class=\"synved-social-button synved-social-button-follow synved-social-size-48 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Follow me on twitter\" href=\"https:\/\/twitter.com\/joboccara\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Follow me on twitter\" class=\"synved-share-image synved-social-image synved-social-image-follow\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/twitter.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-follow synved-social-size-48 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Find us on Linkedin\" href=\"https:\/\/www.linkedin.com\/in\/jonathan-boccara-23826921\/\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Find us on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-follow\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/linkedin.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-follow synved-social-size-48 synved-social-resolution-single synved-social-provider-rss nolightbox\" data-provider=\"rss\" target=\"_blank\" rel=\"nofollow\" title=\"Subscribe to our RSS Feed\" href=\"https:\/\/www.fluentcpp.com\/feed\/\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"rss\" title=\"Subscribe to our RSS Feed\" class=\"synved-share-image synved-social-image synved-social-image-follow\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/rss.png?resize=48%2C48&#038;ssl=1\" \/><\/a><br\/>Share this post!<a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-facebook nolightbox\" data-provider=\"facebook\" target=\"_blank\" rel=\"nofollow\" title=\"Check out this post from Fluent C++\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https%3A%2F%2Fwww.fluentcpp.com%2Fwp-json%2Fwp%2Fv2%2Fposts%2F603&#038;t=The%20Interface%20Principle%20in%20C%2B%2B&#038;s=100&#038;p&#091;url&#093;=https%3A%2F%2Fwww.fluentcpp.com%2Fwp-json%2Fwp%2Fv2%2Fposts%2F603&#038;p&#091;images&#093;&#091;0&#093;=https%3A%2F%2Fwww.fluentcpp.com%2Fwp-content%2Fuploads%2F2017%2F09%2Fdaily-able-content-e1505330890615.png&#038;p&#091;title&#093;=The%20Interface%20Principle%20in%20C%2B%2B\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"Facebook\" title=\"Check out this post from Fluent C++\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/facebook.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Tweet about this\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fwww.fluentcpp.com%2Fwp-json%2Fwp%2Fv2%2Fposts%2F603&#038;text=Check%20out%20this%20post%20from%20Fluent%20C%2B%2B\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Tweet about this\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/twitter.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fwww.fluentcpp.com%2Fwp-json%2Fwp%2Fv2%2Fposts%2F603&#038;title=The%20Interface%20Principle%20in%20C%2B%2B\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/linkedin.png?resize=48%2C48&#038;ssl=1\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>The Interface Principle in C++\u00a0encompasses\u00a0a specific combination of features and ways of considering what\u00a0an interface is, that allows to write expressive C++ code that preserves encapsulation. It has been around for a while, is still currently used, and may\u00a0be enriched in the future versions of the language. So it&#8217;s worth being aware of. Note that [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[45,10,19,16,18,43,46,47,48],"class_list":["post-603","post","type-post","status-publish","format-standard","hentry","category-expressive-code","tag-adl","tag-c","tag-cpp","tag-expressive","tag-fluent","tag-interface","tag-koenig","tag-lookup","tag-namespace"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Interface Principle in C++ - Fluent C++<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Interface Principle in C++ - Fluent C++\" \/>\n<meta property=\"og:description\" content=\"The Interface Principle in C++\u00a0encompasses\u00a0a specific combination of features and ways of considering what\u00a0an interface is, that allows to write expressive C++ code that preserves encapsulation. It has been around for a while, is still currently used, and may\u00a0be enriched in the future versions of the language. So it&#8217;s worth being aware of. Note that [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/\" \/>\n<meta property=\"og:site_name\" content=\"Fluent C++\" \/>\n<meta property=\"article:published_time\" content=\"2017-06-20T01:00:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-09-18T07:08:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png\" \/>\n<meta name=\"author\" content=\"Jonathan Boccara\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@joboccara\" \/>\n<meta name=\"twitter:site\" content=\"@JoBoccara\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jonathan Boccara\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/\"},\"author\":{\"name\":\"Jonathan Boccara\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/#\\\/schema\\\/person\\\/bc2586443e40d356676d1b1740521237\"},\"headline\":\"The Interface Principle in C++\",\"datePublished\":\"2017-06-20T01:00:22+00:00\",\"dateModified\":\"2017-09-18T07:08:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/\"},\"wordCount\":1481,\"commentCount\":14,\"image\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.fluentcpp.com\\\/wp-content\\\/uploads\\\/2017\\\/09\\\/daily-able-content-e1505330890615.png\",\"keywords\":[\"adl\",\"C++\",\"cpp\",\"expressive\",\"fluent\",\"interface\",\"koenig\",\"lookup\",\"namespace\"],\"articleSection\":[\"Expressive code\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/\",\"url\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/\",\"name\":\"The Interface Principle in C++ - Fluent C++\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.fluentcpp.com\\\/wp-content\\\/uploads\\\/2017\\\/09\\\/daily-able-content-e1505330890615.png\",\"datePublished\":\"2017-06-20T01:00:22+00:00\",\"dateModified\":\"2017-09-18T07:08:05+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/#\\\/schema\\\/person\\\/bc2586443e40d356676d1b1740521237\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.fluentcpp.com\\\/wp-content\\\/uploads\\\/2017\\\/09\\\/daily-able-content-e1505330890615.png?fit=120%2C116&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/www.fluentcpp.com\\\/wp-content\\\/uploads\\\/2017\\\/09\\\/daily-able-content-e1505330890615.png?fit=120%2C116&ssl=1\",\"width\":120,\"height\":116,\"caption\":\"Daily C++\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/2017\\\/06\\\/20\\\/interface-principle-cpp\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.fluentcpp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The Interface Principle in C++\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/#website\",\"url\":\"https:\\\/\\\/www.fluentcpp.com\\\/\",\"name\":\"Fluent C++\",\"description\":\"Jonathan Boccara&#039;s blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.fluentcpp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.fluentcpp.com\\\/#\\\/schema\\\/person\\\/bc2586443e40d356676d1b1740521237\",\"name\":\"Jonathan Boccara\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cf2136ea15306047a4aa549b5400deb87e750440abe9f5fab5ea5d8b47349d27?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cf2136ea15306047a4aa549b5400deb87e750440abe9f5fab5ea5d8b47349d27?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cf2136ea15306047a4aa549b5400deb87e750440abe9f5fab5ea5d8b47349d27?s=96&d=mm&r=g\",\"caption\":\"Jonathan Boccara\"},\"description\":\"Hello, my name is Jonathan Boccara, I'm your host on Fluent C++. I have been a developer for 14 years. My focus is on how to write expressive code. I wrote the book The Legacy Code Programmer's Toolbox. I'm happy to take your feedback, don't hesitate to drop a comment on a post, follow me or get in touch directly !\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/jonathan-boccara-23826921\\\/\",\"https:\\\/\\\/x.com\\\/joboccara\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Interface Principle in C++ - Fluent C++","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/","og_locale":"en_US","og_type":"article","og_title":"The Interface Principle in C++ - Fluent C++","og_description":"The Interface Principle in C++\u00a0encompasses\u00a0a specific combination of features and ways of considering what\u00a0an interface is, that allows to write expressive C++ code that preserves encapsulation. It has been around for a while, is still currently used, and may\u00a0be enriched in the future versions of the language. So it&#8217;s worth being aware of. Note that [&hellip;]","og_url":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/","og_site_name":"Fluent C++","article_published_time":"2017-06-20T01:00:22+00:00","article_modified_time":"2017-09-18T07:08:05+00:00","og_image":[{"url":"https:\/\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png","type":"","width":"","height":""}],"author":"Jonathan Boccara","twitter_card":"summary_large_image","twitter_creator":"@joboccara","twitter_site":"@JoBoccara","twitter_misc":{"Written by":"Jonathan Boccara","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#article","isPartOf":{"@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/"},"author":{"name":"Jonathan Boccara","@id":"https:\/\/www.fluentcpp.com\/#\/schema\/person\/bc2586443e40d356676d1b1740521237"},"headline":"The Interface Principle in C++","datePublished":"2017-06-20T01:00:22+00:00","dateModified":"2017-09-18T07:08:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/"},"wordCount":1481,"commentCount":14,"image":{"@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png","keywords":["adl","C++","cpp","expressive","fluent","interface","koenig","lookup","namespace"],"articleSection":["Expressive code"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/","url":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/","name":"The Interface Principle in C++ - Fluent C++","isPartOf":{"@id":"https:\/\/www.fluentcpp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#primaryimage"},"image":{"@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png","datePublished":"2017-06-20T01:00:22+00:00","dateModified":"2017-09-18T07:08:05+00:00","author":{"@id":"https:\/\/www.fluentcpp.com\/#\/schema\/person\/bc2586443e40d356676d1b1740521237"},"breadcrumb":{"@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#primaryimage","url":"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png?fit=120%2C116&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.fluentcpp.com\/wp-content\/uploads\/2017\/09\/daily-able-content-e1505330890615.png?fit=120%2C116&ssl=1","width":120,"height":116,"caption":"Daily C++"},{"@type":"BreadcrumbList","@id":"https:\/\/www.fluentcpp.com\/2017\/06\/20\/interface-principle-cpp\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.fluentcpp.com\/"},{"@type":"ListItem","position":2,"name":"The Interface Principle in C++"}]},{"@type":"WebSite","@id":"https:\/\/www.fluentcpp.com\/#website","url":"https:\/\/www.fluentcpp.com\/","name":"Fluent C++","description":"Jonathan Boccara&#039;s blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.fluentcpp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.fluentcpp.com\/#\/schema\/person\/bc2586443e40d356676d1b1740521237","name":"Jonathan Boccara","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/cf2136ea15306047a4aa549b5400deb87e750440abe9f5fab5ea5d8b47349d27?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/cf2136ea15306047a4aa549b5400deb87e750440abe9f5fab5ea5d8b47349d27?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cf2136ea15306047a4aa549b5400deb87e750440abe9f5fab5ea5d8b47349d27?s=96&d=mm&r=g","caption":"Jonathan Boccara"},"description":"Hello, my name is Jonathan Boccara, I'm your host on Fluent C++. I have been a developer for 14 years. My focus is on how to write expressive code. I wrote the book The Legacy Code Programmer's Toolbox. I'm happy to take your feedback, don't hesitate to drop a comment on a post, follow me or get in touch directly !","sameAs":["https:\/\/www.linkedin.com\/in\/jonathan-boccara-23826921\/","https:\/\/x.com\/joboccara"]}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/posts\/603","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/comments?post=603"}],"version-history":[{"count":23,"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/posts\/603\/revisions"}],"predecessor-version":[{"id":2202,"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/posts\/603\/revisions\/2202"}],"wp:attachment":[{"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/media?parent=603"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/categories?post=603"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fluentcpp.com\/wp-json\/wp\/v2\/tags?post=603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}