{"id":2650,"date":"2017-07-20T06:52:00","date_gmt":"2017-07-20T06:52:00","guid":{"rendered":"https:\/\/intelligentbee.com\/blog\/?p=2650"},"modified":"2024-12-13T08:16:23","modified_gmt":"2024-12-13T08:16:23","slug":"oop-golang-vs-c","status":"publish","type":"post","link":"https:\/\/intelligentbee.com\/blog\/oop-golang-vs-c\/","title":{"rendered":"OOP in Golang vs C++"},"content":{"rendered":"<p>Before I started to learn Go, every online opinion I would read about the language complained about the lack of generics and how OOP was dumbed down \u00a0and so on.<\/p>\n<p>It made me put off learning it for quite some time, more than I would like to admit. Coming from a C++ background, OOP, generics and meta-programming was my daily bread.<\/p>\n<p>It wasn&#8217;t until I had to actually learn Go that I saw what it offered me in terms of OOP and it was just enough. As such, I wanted to put a side-by-side comparison of typical C++ code that deals with classes, and it&#8217;s corresponding implementation in Go that does more or less the same thing.<\/p>\n<p>This is by no means an exhaustive list of examples, but I thought it might prove useful for someone trying to figure out Go.<\/p>\n<p>To run all Go examples, copy them to a file and run\u00a0<span class=\"lang:default decode:true crayon-inline \">go run filename.go<\/span>\u00a0.<\/p>\n<p>To run all C++ \u00a0examples, copy them to a file and run\u00a0<span class=\"lang:default decode:true crayon-inline \">g++ -o filename filename.cpp -std=c++14 &amp;&amp; .\/filename<\/span>\u00a0.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_68_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/intelligentbee.com\/blog\/oop-golang-vs-c\/#Class_declaration\" title=\"Class declaration\">Class declaration<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/intelligentbee.com\/blog\/oop-golang-vs-c\/#Inheritance_sort_of\" title=\"Inheritance (sort of)\">Inheritance (sort of)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/intelligentbee.com\/blog\/oop-golang-vs-c\/#Interfaces\" title=\"Interfaces\">Interfaces<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/intelligentbee.com\/blog\/oop-golang-vs-c\/#Conclusion\" title=\"Conclusion\">Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Class_declaration\"><\/span>Class declaration<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In C++:<\/p>\n<pre class=\"lang:c++ decode:true \" title=\"Class declaration\">#include &lt;iostream&gt;\r\n#include &lt;memory&gt;\r\n#include &lt;string&gt;\r\n\r\nclass MyClass {\r\n    private:\r\n        std::string property1;\r\n\r\n        void Method1(std::string param1, int param2);\r\n\r\n    public:\r\n        std::string property2;\r\n\r\n        MyClass(std::string constructor_argument);\r\n        int Method2(int param);\r\n};\r\n\r\nMyClass::MyClass(std::string constructor_argument) {\r\n    this-&gt;property1 = constructor_argument;\r\n}\r\n\r\nvoid MyClass::Method1(std::string param1, int param2) {\r\n    std::cout &lt;&lt; param1 &lt;&lt; std::endl &lt;&lt; param2 &lt;&lt; std::endl;\r\n    std::cout &lt;&lt; this-&gt;property2 &lt;&lt; std::endl;\r\n}\r\n\r\nint MyClass::Method2(int param) {\r\n    this-&gt;Method1(this-&gt;property1, param);\r\n\r\n    return param + 1;\r\n}\r\n\r\nint main(int argc, char *argv[]) {\r\n    auto obj = std::make_unique&lt;MyClass&gt;(\"property 1 value\");\r\n\r\n    obj-&gt;property2 = \"property 2 value\";\r\n\r\n    std::cout &lt;&lt; obj-&gt;Method2(4) &lt;&lt; std::endl;\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Go equivalent:<\/p>\n<pre class=\"lang:go decode:true \" title=\"Class declaration\">package main\r\n\r\nimport \"fmt\"\r\n\r\ntype MyClass struct {\r\n\t\/\/ properties that start with a lowercase character are private\r\n\tproperty1 string\r\n\t\/\/ properties that start with an uppercase character are public\r\n\tProperty2 string\r\n\r\n\t\/*\r\n\t\tKeep in mind that public and private in Golang actually\r\n\t\tmeans exported by package. Code from the same package\r\n\t\tcan access a structure's private properties and methods.\r\n\t*\/\r\n}\r\n\r\nfunc NewMyClass(constructor_argument string) *MyClass {\r\n\treturn &amp;MyClass{property1: constructor_argument}\r\n}\r\n\r\nfunc (mc *MyClass) method1(param1 string, param2 int) {\r\n\tfmt.Printf(\"%s\\n%d\\n\", param1, param2)\r\n\tfmt.Printf(\"%s\\n\", mc.property1)\r\n}\r\n\r\nfunc (mc *MyClass) Method2(param int) int {\r\n\tmc.method1(mc.property1, param)\r\n\r\n\treturn param + 1\r\n}\r\n\r\nfunc main() {\r\n\tobj := NewMyClass(\"property 1 value\")\r\n\r\n\tobj.Property2 = \"property 2 value\"\r\n\r\n\tfmt.Printf(\"%d\\n\", obj.Method2(4))\r\n\r\n\t\/\/ No return needed\r\n}\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Inheritance_sort_of\"><\/span>Inheritance (sort of)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In C++:<\/p>\n<pre class=\"lang:c++ decode:true \" title=\"Inheritance\">#include &lt;iostream&gt;\r\n#include &lt;memory&gt;\r\n#include &lt;string&gt;\r\n\r\nclass BaseClass {\r\n    public:\r\n        std::string property1;\r\n        void method1();\r\n};\r\n\r\nvoid BaseClass::method1() {\r\n    std::cout &lt;&lt; this-&gt;property1 &lt;&lt; std::endl;\r\n}\r\n\r\nclass DerivedClass : public BaseClass {\r\n    public:\r\n        std::string property2;\r\n        void method2();\r\n};\r\n\r\nvoid DerivedClass::method2() {\r\n    std::cout &lt;&lt; this-&gt;property2 &lt;&lt; std::endl;\r\n}\r\n\r\nint main(int argc, char *argv[]) {\r\n    auto obj = std::make_unique&lt;DerivedClass&gt;();\r\n    obj-&gt;property1 = \"property 1 value\";\r\n    obj-&gt;property2 = \"property 2 value\";\r\n\r\n    obj-&gt;method1();\r\n    obj-&gt;method2();\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Go equivalent:<\/p>\n<pre class=\"lang:go decode:true \" title=\"Inheritance\">package main\r\n\r\nimport \"fmt\"\r\n\r\ntype BaseClass struct {\r\n\tProperty1 string\r\n\r\n\t\/\/ no need for method declaration here\r\n}\r\n\r\nfunc (bc *BaseClass) Method1() {\r\n\tfmt.Printf(\"%s\\n\", bc.Property1)\r\n}\r\n\r\ntype DerivedClass struct {\r\n\tBaseClass \/\/ this is actually composition\r\n\r\n\tProperty2 string\r\n}\r\n\r\nfunc (dc *DerivedClass) Method2() {\r\n\tfmt.Printf(\"%s\\n\", dc.Property2)\r\n}\r\n\r\nfunc main() {\r\n\tobj := &amp;DerivedClass{}\r\n\tobj.Property1 = \"property 1 value\"\r\n\tobj.Property2 = \"property 2 value\"\r\n\r\n\tobj.Method1()\r\n\tobj.Method2()\r\n\r\n\t\/\/ no need to return\r\n}\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Interfaces\"><\/span>Interfaces<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In C++:<\/p>\n<pre class=\"lang:c++ decode:true \" title=\"Interfaces\">#include &lt;iostream&gt;\r\n#include &lt;memory&gt;\r\n#include &lt;string&gt;\r\n\r\nclass MyInterface {\r\n    public:\r\n        virtual void method() = 0;\r\n};\r\n\r\nclass Class1 : public MyInterface {\r\n    public:\r\n        void method() override;\r\n};\r\n\r\nvoid Class1::method() {\r\n    std::cout &lt;&lt; \"Class 1\" &lt;&lt; std::endl;\r\n}\r\n\r\nclass Class2 : public MyInterface {\r\n    public:\r\n        void method() override;\r\n};\r\n\r\nvoid Class2::method() {\r\n    std::cout &lt;&lt; \"Class 2\" &lt;&lt; std::endl;\r\n}\r\n\r\nstd::shared_ptr&lt;MyInterface&gt; NewClass1() {\r\n    return std::make_shared&lt;Class1&gt;();\r\n}\r\n\r\nstd::shared_ptr&lt;MyInterface&gt; NewClass2() {\r\n    return std::make_shared&lt;Class2&gt;();\r\n}\r\n\r\nint main(int argc, char *argv[]) {\r\n    auto obj1 = NewClass1();\r\n    auto obj2 = NewClass2();\r\n\r\n    obj1-&gt;method();\r\n    obj2-&gt;method();\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Go equivalent:<\/p>\n<pre class=\"lang:go decode:true\" title=\"Interfaces\">package main\r\n\r\nimport \"fmt\"\r\n\r\ntype MyInterface interface {\r\n\tMethod()\r\n}\r\n\r\ntype Class1 struct {\r\n}\r\n\r\nfunc (c1 *Class1) Method() {\r\n\tfmt.Println(\"Class 1\")\r\n}\r\n\r\ntype Class2 struct {\r\n}\r\n\r\nfunc (c2 *Class2) Method() {\r\n\tfmt.Println(\"Class 2\")\r\n}\r\n\r\nfunc NewClass1() MyInterface {\r\n\treturn &amp;Class1{}\r\n}\r\n\r\nfunc NewClass2() MyInterface {\r\n\treturn &amp;Class2{}\r\n}\r\n\r\nfunc main() {\r\n\tobj1 := NewClass1()\r\n\tobj2 := NewClass2()\r\n\r\n\tobj1.Method()\r\n\tobj2.Method()\r\n}\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>There are basic equivalences between traditional OOP languages like C++ and the syntax and functionality that Golang provides.<\/p>\n<p>In it&#8217;s own simple way, Golang provides ways to implement encapsulation, inheritance and polymorphism. In my humble opinion, these mechanisms are enough for most object-oriented projects.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Before I started to learn Go, every online opinion I would read about the language complained about the lack of [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":2709,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[73,78,86],"tags":[],"yst_prominent_words":[281,809,970,1013,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/2650"}],"collection":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/comments?post=2650"}],"version-history":[{"count":4,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/2650\/revisions"}],"predecessor-version":[{"id":133355,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/2650\/revisions\/133355"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media\/2709"}],"wp:attachment":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media?parent=2650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/categories?post=2650"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/tags?post=2650"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=2650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}