提问人:KajzerSoze 提问时间:10/19/2023 最后编辑:KajzerSoze 更新时间:10/19/2023 访问量:85
如果对象是在库中定义的,为什么静态创建的对象的构造函数不会在 main 函数之前执行?
Why constructor of a statically created object is not executed before main function if the object is defined in library?
问:
我正在尝试创建“插件”工厂。当用户请求创建对象工厂时,会查询其子工厂,并选择合适的子工厂来创建对象。
子库的实例是静态对象。创建后,它们将自己注册到顶级工厂。
以下是简化版本:
// ifactory.h
#ifndef _IFACTORY_H_
#define _IFACTORY_H_
#include <string>
class IFactory {
public:
virtual int createNumber(const std::string& name, std::pair<int, int> range) = 0;
virtual std::string getName() const = 0;
virtual ~IFactory() = default;
};
#endif
// defaul_factory.h:
#ifndef _DEFAULT_FACTORY_H_
#define _DEFAULT_FACTORY_H_
#include "ifactory.h"
#include <vector>
#include <stdexcept>
class DefaultFactory : public IFactory {
public:
int createNumber(const std::string& name, std::pair<int, int> range) override {
for (auto factory: g_factories) {
if (factory->getName() == name) {
return factory->createNumber(name, range);
}
}
throw std::runtime_error{"No factory can create requested number"};
}
std::string getName() const override {
return "default";
}
static void registerFactory(IFactory* factory) {
g_factories.push_back(factory);
}
private:
static std::vector<IFactory*> g_factories;
};
#endif
// defalut_factory.cpp
#include "default_factory.h"
std::vector<IFactory*> DefaultFactory::g_factories;
// even_factory.cpp
#include "default_factory.h"
class EvenFactory : public IFactory {
public:
EvenFactory() {
DefaultFactory::registerFactory(this);
}
int createNumber(const std::string& name, std::pair<int, int> range) override {
return range.first % 2 == 0 ? range.first + 4 : range.first + 3;
}
std::string getName() const override {
return "even";
}
};
// Hopefully registers itself to the default factory
static EvenFactory evenFactory;
// main.cpp
#include "default_factory.h"
#include <iostream>
int main() {
DefaultFactory factory;
std::cout << factory.createNumber("even", {100, 200}) << std::endl;
}
# Makefile:
all: foo
foo: libdefault_factory.so libeven_factory.so main.cpp
$(CXX) -L./ -o foo main.cpp -ldefault_factory -Wl,--no-as-needed -leven_factory
libdefault_factory.so: default_factory.cpp default_factory.h ifactory.h
$(CXX) -shared -fPIC -o libdefault_factory.so default_factory.cpp
libeven_factory.so: even_factory.cpp default_factory.h ifactory.h
$(CXX) -shared -fPIC -o libeven_factory.so even_factory.cpp
bar: default_factory.cpp even_factory.cpp default_factory.h ifactory.h main.cpp
$(CXX) -o bar main.cpp default_factory.cpp even_factory.cpp
.PHONY: clean
clean:
rm foo bar *.so
当我执行时,我得到一个运行时异常,该异常是从 抛出的,就好像构造函数没有运行一样。foo
DefalutFactory
evenFactory
按预期运行打印。bar
104
为什么不为构造函数调用?foo
注意:我使用 g++ 版本 9 和 g++ 版本 10.2 测试了该示例。
答: 暂无答案
评论
-leven_factory
什么也不做。库外部的任何对象都引用该库中的任何内容,因此它根本没有链接。你想要之前.(通过运行 进行验证)。(我认为 --no-as-needed 曾经是默认设置,但 Ubuntu 和其他可能的人最近改变了这一点)。-Wl,--no-as-needed
-leven_factory
ldd foo
evenFactory
g_factories