是否有可能每个类只传递一次变量但不能使它变为静态变量?

can*_*ust 4 c++

这个问题(松散地)与我昨天在这里提出的问题有关.

我刚刚重构了一个容器类(Ecosystem),它包含指向Individuals的指针:

class Ecosystem
{
    // This is an interface class providing access
    // to functions in Individual without exposing
    // the Individual class.
    // It performs global operations on the entire ecosystem
    // (like sorting individuals based on certain criteria)
    // but is also capable of invoking functions from the
    // Individual class.
    // It also holds the global configuration for this ecosystem.
    private:
        Config config;
        std::map<int, std::shared_ptr<Individual> > individuals;
    public:
        Ecosystem() {};
        void sort_individuals();
        void func1(int _individual_id)
        {
            individuals[_individual_id]->func1(config);
        }

        void func2(int _individual_id)
        {
            individuals[_individual_id]->func2(config);
        }
        // etc...
};

class Individual
{
    private:

    public:
        Individual() {};
        void func1(const Config& _config)
        {
            // Operations using _config.param_1, _config.param_2, ... 
        }

        void func2(const Config& _config)
        {
            // Operations using _config.param_n, _config.param_m, ... 
        }
        // etc...
}
Run Code Online (Sandbox Code Playgroud)

我现在处于这样的情况,我必须通过config几乎每个函数调用Individual对象.最初我想,好吧,我只是做一个static Config config;内部Individual,但很快我意识到我需要能够创建具有不同配置的多个共存生态系统.

如果我理解static正确的含义,如果我static Config config;Individual其中分配了configfrom 的值Ecosystem,那么每次我创建一个新的生态系统时它都会被覆盖.

我的问题是:有没有办法将config 一次传递给Individual类而不使其为静态,以避免将其作为每个函数的参数传递?

我曾考虑有Config* config两个EcosystemIndividual,但是这意味着每个人都会有一个指向配置对象,这似乎是笨重.我需要的是等效的静态成员,其范围可以识别容器层次结构,如果这有意义的话.

一旦创建,Config对象将不会被更改,因此可以有一个const Config config;.

提前感谢您的任何建议!


编辑1

谢谢大家的回复.马修克劳斯有一个观点,我在原始问题中没有提供我的生态系统类的正确构造函数,当然,这是对我的疏忽.我现在看到它可能是相关的,但我更专注于说明我所追求的变量访问类型而不是我的类的外观,所以我提出了一个简单的例子.如果我用额外的评论引起讨论的混乱,我会道歉!

这里提出的解决方案都非常好,但我可以从答案中看出,C++没有任何方法来定义这样的类级变量而不将它们定义为static.我需要的是一个类级变量,其范围仅限于其容器.这只是我的想法的一个例子,它不会编译(我现在肯定这不能在C++中完成):

class Ecosystem
{
    // This is an interface class providing access
    // to functions in Individual without exposing
    // the Individual class.
    // It performs global operations on the entire ecosystem
    // (like sorting individuals based on certain criteria)
    // but is also capable of invoking functions from the
    // Individual class.
    // It also holds the global configuration for this ecosystem.

    private:

        Config config;
        std::map<int, std::shared_ptr<Individual> > individuals;

    public:
        Ecosystem(const std::string& _file_name)
        {
            Config cfg(_file_name);

            config = cfg;

            // This is done before any Individual objects are created.
            Individual::set_config(cfg);

            for (int i = 1; i <= 10; ++i)
            {
                individuals[i] = std::make_shared<Individual>();
            }
        };

        void sort_individuals();

        void func1(int _individual_id)
        {
            individuals[_individual_id]->func1();
        }

        void func2(int _individual_id)
        {
            individuals[_individual_id]->func2();
        }
        // etc...
};

class Individual
{
    private:
        // v--- No such thing!
        scoped static Config config;

    public:
        Individual() {};

        void func1()
        {
            // Operations using config.param_1, config.param_2, ... 
        }

        void func2()
        {
            // Operations using config.param_n, config.param_m, ...
        }

        // v--- No such thing!
        scoped static void set_config(const Config& _config)
        {
            config = _config;
        }
        // etc...
}

int main(int argc, char* argv[])
{
    Ecosystem ecosystem1("config_file1.txt");

    Ecosystem ecosystem2("config_file2.txt");

    // Conduct experiments with the two ecosytems.
    // Note that when ecosystem2 is created, the line
    //
    // Individual::set_config(cfg);
    //
    // should *not* overwrite the class-level variable
    // config set when ecosystem1 was created. 
    // Instead, it should create a
    // class-level variable but limited to the scope of ecosystem 2.

    // This operates on Individual 1 in ecosystem 1
    // with the parameters set in config_file1.txt
    ecosystem1->func1(1);

    // This operates on Individual 1 in ecosystem 2
    // with the parameters set in config_file2.txt
    ecosystem2->func1(1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我将建议在构造时将指针传递给每个人.这会浪费空间,但应该是最容易维护的解决方案.

再次感谢大家的意见,如果问题令人困惑,请道歉.

Mak*_*jov 6

如果我理解正确,将配置传递给an的构造函数Individual应该:

class Individual {
    const Config& config_;
public:
    Individual(const Config& c) : config_(c) {}
    void func1() {
        // use config_
    }
};
Run Code Online (Sandbox Code Playgroud)

你仍然需要传递Config给每个单独的构造函数,但这只是一个单点,而不是许多函数Individual都有.此外,Individual如果您觉得创建过于繁琐,您可以将创建封装到工厂方法中.