3

マップのローカル静的オブジェクトを使用して、作成できるすべてのクラスの名前を保持するクラス ファクトリを作成しました。

typedef std::map<std::string, ClassFactory*> typeMap;

static typeMap& getMap() {
    static typeMap map;
    return map;
}

クラスは、次のコードを使用してマップに登録する必要があります。

DerivedRegistering(std::string const& s) {
    std::cout << "Inserting " << s << std::endl;
    std::cout << "Map size " << getMap().size() << std::endl;
    getMap().insert(std::make_pair(s, this));
}

新しいインスタンスを作成する場合createInstanceは、クラスの静的関数を呼び出します。

static Object* createInstance(std::string const& s) {
    std::cout << "Current map size " << getMap().size() << std::endl;
    typeMap::iterator it = getMap().find(s);
    if(it == getMap().end()) // not registered
        return 0;
    return it->second->create();
}

ライブラリ A のヘッダー ファイルにこのクラス ファクトリを作成し、別の動的ライブラリ B をリンクして最終的に実行可能ファイルを作成するプロジェクトにライブラリ A を動的にリンクしているとします。

現在、Linux で gcc を使用している場合、これに関する問題は発生していませんが、mingw を使用して Windows で同じことを行うと、問題が発生します。

gcc の出力:

Registering classes of library B:
Inserting BA
Map size 0
Inserting BB
Map size 1
Inserting BC
Map size 2
Inserting BD
Map size 3
Inserting BE
Map size 4

Registering classes of library A:
Inserting AA
Map size 5
Inserting AB
Map size 6
Inserting AC
Map size 7
Inserting AD
Map size 8
Inserting AE
Map size 9
Inserting AF
Map size 10
Inserting AG
Map size 11

calling create instance in executable:
Current map size 12

ただし、mingw では、次のような出力が得られます。

Registering classes of library B:
Inserting BA
Map size 0
Inserting BB
Map size 1
Inserting BC
Map size 2
Inserting BD
Map size 3
Inserting BE
Map size 4

Registering classes of library A:
Inserting AA
Map size 0
Inserting AB
Map size 1
Inserting AC
Map size 2
Inserting AD
Map size 3
Inserting AE
Map size 4
Inserting AF
Map size 5
Inserting AG
Map size 6

calling create instance in executable:
Current map size 0

したがって、mingw はライブラリと実行可能ファイルごとに新しい静的ローカル マップを作成するように見えますが、gcc はそれらすべてに同じメモリを使用します。

ご想像のとおり、GCC の動作は望ましいものです。これをmingwに適用できますか?

4

1 に答える 1

4

関数は静的で、複数の場所に含まれています。つまり、別個のボディと別個のオブジェクトが作成されます。

.h で関数 extern を作成し、.cpp ファイルに単一の本体を追加すると、シングルトンが作成されます。

または、同じ効果を得るために静的ではなくインラインにすることもできます。

于 2013-06-10T09:54:49.377 に答える