跨多个源文件构建C ++静态数组

时间:2014-07-24 19:33:11

标签: c++

我的系统看起来像这样:

Master.h

extern const Activators[2];

Master.cpp

#include <TypeOne.h>
#include <TypeTwo.h>
const Activators[2] = { &TypeOne::Create, &TypeTwo::Create };

你可以想象TypeOne和TypeTwo是带有静态Create方法的类,它返回一个新实例。

我正在寻找一种方法来分解这个系统,这样就不需要成为一个单独的文件来创建所有类型的链接时依赖。

我希望能够将单元测试与仅仅TypeOne的目标文件和静态Activators数组的版本链接在一起,该数组仅填充了TypeOne创建的函数指针方法。

在C ++中是否有办法创建静态定义的数组,然后在编译单元中填充该数组中的各个插槽?理想情况下,我能够拥有这样的东西:

Master.cpp

const Activators[2];

TypeOne.cpp

Activators[0] = &TypeOne::Create;

TypeTwo.cpp

Activators[1] = &TypeTwo::Create;

4 个答案:

答案 0 :(得分:0)

是。虽然你需要非常小心。

TypeOne.cpp

namespace {
    class BeforeMain {
        BeforeMain() {
            Activators[0] = &TypeOne::Create;
        }
    };

    BeforeMain obj;
}

TypeTwo.cpp

namespace {
    class BeforeMain {
        BeforeMain() {
            Activators[1] = &TypeTwo::Create;
        }
    };

    BeforeMain obj;
}

然后,除此之外,在调用main()之前,不要访问数组。

就个人而言,我希望Activators成为std::vector<T>,然后让每个BeforeMain使用std::vector<T>::push_back()

答案 1 :(得分:0)

假设Activators是一个多态性(Type1Type2都来自Activators)类型,我会像这样处理问题。

Activators.h

std::vector<std::unique_ptr>>& activators();

Activators.cpp

std::vector<std::unique_ptr>>& activators()
{
   static std::vector<std::unique_ptr>> the_array(2);
   return the_array;
}

然后在各个编辑单元中,您可以指定任何您想要的内容:

Type1.cpp

#include "Activators.h"

struct setup_activator_type_1
{
    setup_activator_type_1()
    {
       activators()[0].reset(new Type1);
    }
};

static setup_activator_type_1 type1_static_initializer;

答案 2 :(得分:0)

我会提供一个功能界面来添加Activators并使用 TypeOne.cpp TypeTwo.cpp

Activators.h

void addActivator(Activator activator);

Activators.cpp

static std::vector<Activator> activators{};

void addActivator(Activator activator)
{
   activators.push_back(activator);
}

TypeOne.cpp

struct Initializer
{
   Initializer()
   {
      addActivator(&TypeOne::Create);
   }
};

static Initializer initializer;

TypeTwo.cpp

struct Initializer
{
   Initializer()
   {
      addActivator(&TypeTwo::Create);
   }
};

static Initializer initializer;

答案 3 :(得分:0)

C ++初始化全局变量的方式是真的很奇怪,从技术上讲,到目前为止其他答案都有未定义的行为,但无论如何都可能适用于你的机器/编译器。基本上,问题是当程序启动时,实现只需要初始化main.cpp及其标题中的全局变量。当您的代码调用另一个cpp / header组合(翻译单元)中定义的函数时,只有才需要C ++来初始化该一个翻译单元中的全局

您的特定情况中最简单(安全)的解决方法是简单地在标头中进行初始化。如果文件包含include "TypeOne.h",则会自行初始化Activators[0]。为了便于携带,包含int main()的翻译单元(cpp文件)还包括您需要使用的所有这些标题,这一点非常重要。否则,您无法在main开始之前对其进行初始化。

TypeOne.h中的

#include "master.h"

class TypeOne { 
    static std::unique_ptr<TypeOne> Create();
    //stuff
};
static const auto TypeOneInitialized = Activators[0] = &TypeOne::Create;

如果您有一个不应该依赖TypeTwo的cpp,请不要包含它的标题。