が静的ライブラリの場合は、参照されていない静的オブジェクトは作成されませんか?
、CMAKEを環境GNU GCC(G ++)4.1.2の開発(私は、この本はかなり古いであることを認めなければならない。あなたのため、一部の私は、Exemplarイディオムが継承クラス階層間の依存関係を損なうのに非常に有用であることを発見しました。次のように、このイディオムを扱うための簡単なプロジェクトを作成しようとしました。
あらかじめご了承いただき、ありがとうございます。ソースコード全体を次のように記載しています。 base.cppでbase.h
#ifndef BASE_H_
#define BASE_H_
#include <string>
class Exemplar;
class Base
{
public:
Base(Exemplar /* no use */);
Base();
virtual Base* make(const std::string& key);
virtual void memberMethod1();
virtual int memberMethod2();
virtual ~Base() {};
protected:
static Base* list_;
Base* next_;
};
#else
#endif // BASE_H_
でexemplar.h
#ifndef EXEMPLAR_H_
#define EXEMPLAR_H_
class Exemplar
{
public:
Exemplar() {};
};
#else
#endif // EXEMPLAR_H_
でCMakeLists.txt
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)
で
#include <string>
#include <iostream>
#include "exemplar.h"
#include "base.h"
Base* Base::list_ = 0;
static Exemplar exemplar;
static Base baseInstance(exemplar);
Base* baseExemplar = &baseInstance;
Base::Base(Exemplar /* no use */) : next_(list_)
{
std::cout << "Base object exemplar ctor" << std::endl;
list_ = this;
}
Base::Base() : next_(0) {}
Base* Base::make(const std::string& key)
{
Base* retval = 0;
for (Base* a = list_; a; a = a->next_)
{
if (a != baseExemplar)
{
if ((retval = a->make(key)))
{
break;
}
}
else if (key == "base")
{
retval = new Base();
break;
}
}
return retval;
}
void Base::memberMethod1()
{
std::cout << "base class memberMethod1() called." << std::endl;
}
int Base::memberMethod2()
{
std::cout << "base class memberMethod2() called." << std::endl;
return 0;
}
main.cppに
#include "base.h"
extern Base* baseExemplar;
int main()
{
Base *ptr = baseExemplar->make("derived1");
if (ptr) {
ptr->memberMethod1();
ptr->memberMethod2();
}
Base *ptr2 = baseExemplar->make("base");
if (ptr2) {
ptr2->memberMethod1();
ptr2->memberMethod2();
}
return 0;
}
でderived1.h derived1.cpp
#include <iostream>
#include "exemplar.h"
#include "derived1.h"
static Exemplar exemplar;
static Derived1 derived1Exemplar(exemplar);
Derived1::Derived1(Exemplar a) : Base(a)
{
std::cout << "Derived object exemplar ctor" << std::endl;
}
Derived1::Derived1() : Base() {}
Derived1* Derived1::make(const std::string& key)
{
Derived1* retval = 0;
if (key == "derived1")
{
retval = new Derived1();
}
return retval;
}
void Derived1::memberMethod1()
{
std::cout << "Derived1::memberMethod1" << std::endl;
}
int Derived1::memberMethod2()
{
/* dummy */
std::cout << "Derived1::memberMethod2" << std::endl;
return 0;
}
で
#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& key);
virtual void memberMethod1();
virtual int memberMethod2();
};
#else
#endif // DERIVED1_H_
で
我々は少し代入することにより、共有オブジェクトを作成するために、CMakeLists.txtを変更キーワード 'STATIC'を 'SHARED'とすると、私は期待した動作を見ることができました。私は、(Exemplar argを使って)Derived1クラスオブジェクトの静的オブジェクト作成の結果、Baseクラスのリンクリストチェーンが適切に維持されていることが分かりました。その後、main()の基本オブジェクトから仮想make()メソッドを呼び出すと、Derived1オブジェクトとBaseオブジェクトの両方が "derived1"と "base"というキーストリングを指定することによって正常に作成されたことがわかりました。
ただし、「SHARED」というキーワードを「STATIC」に戻すと、別の結果が表示されます。このような静的オブジェクト(Derived1のExampleオブジェクト)はまったく作成されていないようです。そのため、make( "derived1")メンバーメソッドを呼び出すことによってDerived1オブジェクトの作成に失敗しました。
スタティックライブラリの場合でもこの問題を回避する方法はありますか?私は静的オブジェクトコンストラクタの副作用がBaseクラスのリンクリストに期待したいと思います。
ここで私がしようとしていることがあなたに合っているかどうかは確かではありません。しかし、あなたが私に上記のポインタを与えることができれば非常に感謝します。
ありがとうございました。私が上記のポイントに従って何が起こるかを見ると、私は期待したものの正しい振る舞いを見ることができました。 – Smg