Note that there are some explanatory texts on larger screens.

plurals
  1. POStatic object that is not referenced will not be created in case of static library?
    primarykey
    data
    text
    <p>Developing environment GNU GCC (g++) 4.1.2, CMAKE</p> <p>After I read some authoritative book named 'Advanced C++ Programing Styles and Idioms by James Coplien (I must admit that this book is quite old. So some of you may find it a sort of out-dated.), I found the 'Exemplar idiom' was quite useful to impair the inter-dependency among inheritance class hierarchy. So tried to create simple project for handling this idiom as follows.</p> <p>Thank you for your patience in advance while I list the entire source code as follows.</p> <p>In CMakeLists.txt</p> <pre><code>cmake_minimum_required(VERSION 2.6) project(TestProject) add_library(exemplar_idiom STATIC base.cpp derived1.cpp) add_executable(exemplar_example main.cpp) target_link_libraries(exemplar_example exemplar_idiom) set_target_properties(exemplar_example PROPERTIES OUTPUT_NAME exemplar_example) </code></pre> <p>In exemplar.h</p> <pre><code>#ifndef EXEMPLAR_H_ #define EXEMPLAR_H_ class Exemplar { public: Exemplar() {}; }; #else #endif // EXEMPLAR_H_ </code></pre> <p>In base.h</p> <pre><code>#ifndef BASE_H_ #define BASE_H_ #include &lt;string&gt; class Exemplar; class Base { public: Base(Exemplar /* no use */); Base(); virtual Base* make(const std::string&amp; key); virtual void memberMethod1(); virtual int memberMethod2(); virtual ~Base() {}; protected: static Base* list_; Base* next_; }; #else #endif // BASE_H_ </code></pre> <p>In base.cpp</p> <pre><code>#include &lt;string&gt; #include &lt;iostream&gt; #include "exemplar.h" #include "base.h" Base* Base::list_ = 0; static Exemplar exemplar; static Base baseInstance(exemplar); Base* baseExemplar = &amp;baseInstance; Base::Base(Exemplar /* no use */) : next_(list_) { std::cout &lt;&lt; "Base object exemplar ctor" &lt;&lt; std::endl; list_ = this; } Base::Base() : next_(0) {} Base* Base::make(const std::string&amp; key) { Base* retval = 0; for (Base* a = list_; a; a = a-&gt;next_) { if (a != baseExemplar) { if ((retval = a-&gt;make(key))) { break; } } else if (key == "base") { retval = new Base(); break; } } return retval; } void Base::memberMethod1() { std::cout &lt;&lt; "base class memberMethod1() called." &lt;&lt; std::endl; } int Base::memberMethod2() { std::cout &lt;&lt; "base class memberMethod2() called." &lt;&lt; std::endl; return 0; } </code></pre> <p>In derived1.h</p> <pre><code>#include "base.h" #ifndef DERIVED1_H_ #define DERIVED1_H_ class Exemplar; class Derived1 : public Base { public: Derived1(Exemplar /* no use */); // Conventional default constructor which will be used to instantiate normal object Derived1(); virtual Derived1* make(const std::string&amp; key); virtual void memberMethod1(); virtual int memberMethod2(); }; #else #endif // DERIVED1_H_ </code></pre> <p>In derived1.cpp</p> <pre><code>#include &lt;iostream&gt; #include "exemplar.h" #include "derived1.h" static Exemplar exemplar; static Derived1 derived1Exemplar(exemplar); Derived1::Derived1(Exemplar a) : Base(a) { std::cout &lt;&lt; "Derived object exemplar ctor" &lt;&lt; std::endl; } Derived1::Derived1() : Base() {} Derived1* Derived1::make(const std::string&amp; key) { Derived1* retval = 0; if (key == "derived1") { retval = new Derived1(); } return retval; } void Derived1::memberMethod1() { std::cout &lt;&lt; "Derived1::memberMethod1" &lt;&lt; std::endl; } int Derived1::memberMethod2() { /* dummy */ std::cout &lt;&lt; "Derived1::memberMethod2" &lt;&lt; std::endl; return 0; } </code></pre> <p>In main.cpp</p> <pre><code>#include "base.h" extern Base* baseExemplar; int main() { Base *ptr = baseExemplar-&gt;make("derived1"); if (ptr) { ptr-&gt;memberMethod1(); ptr-&gt;memberMethod2(); } Base *ptr2 = baseExemplar-&gt;make("base"); if (ptr2) { ptr2-&gt;memberMethod1(); ptr2-&gt;memberMethod2(); } return 0; } </code></pre> <p>When we change the CMakeLists.txt slightly to create shared object by substituting the keyword of 'STATIC' as 'SHARED', then I could see the behavior that I expected. I could see that as a result of static object creation of Derived1 class object (with Exemplar arg), the link list chain in the Base class is properly maintained. And after that, when invoking the virtual make() method from the base exemplar object in main(), I could see both Derived1 object and Base object were successfully created by specifying key string of "derived1" and "base".</p> <p>However, if I revert back the keyword 'SHARED' to 'STATIC', then I could see the different result. It seems that such static object (Derived1 exemplar object) is not created at all. So it failed to create the Derived1 object by invoking make("derived1") member method.</p> <p>Is there any way to avoid this issue, even in the case of static library? I would like to expect static object constructor's side-effect towards Base class' link list.</p> <p>I'm not exactly sure of whether what I'm trying to make here is making sense to you. However, it would be greatly appreciated if you could give me the pointer on the above.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload