0

目前我从 Java 切换到 C++,这让我很难过(但有很多新经验 ^^)。我正在编写一些包含我的程序配置的数据传输对象。我已经写了一些类,现在我想要一个行为像容器的类。

这是容器的标题:

class MyContainer{

public:
MyContainer();
virtual ~MyContainer();

Config getConfig(TypeEnum type) {
    switch (type) {
    case ATYPE:
        return config_a;
    case BTYPE:
        return config_b;
    default:
        break;
    }

}

ConfigA config_a;
    ConfigB config_b;
};

配置中有一些数据,并且是从另一个配置文件派生的。

这是 C++ 源代码:

 MyContainer::MyContainer(){
  ConfigA config_a(int c = 1);
  ConfigB config_b(double b = 2.1);
  this->config_a = config_a;
  this->config_b = config_b;
}

我认为有几个问题。但对我来说主要的问题是: 我怎样才能让这个容器中的这些配置共享给我程序的其他模块?我试图使 config_a 指向一个指针,但我总是收到这些类型不匹配的错误消息。

 this->config_a = &config_a; //If ConfigA config_a; was ConfigA *config_a; instead

如果您还有一分钟时间给我,请告诉我getConfig-Method 是否可以这样工作。

如果还有其他主题,请分享。谢谢。

4

2 回答 2

1

你的代码:

ConfigA config_a(int c = 1);

表示返回 ConfigA 并采用默认值为 1 的 int 的函数原型。但如果将 int 声明与表达式分开,它将变为其他内容:

int c;
ConfigA config_a(c = 1); //  This is construction of a ConfigA object

我会这样写构造函数:

MyContainer::MyContainer(int c = 1, double d = 2.1)
 :    config_a (c), config_b (d)  //  Construct the members in the intialization line
{
}

如果要共享指向这些成员的指针,请返回如下指针:

ConfigA * MyContainer::GetConfigA(){return &config_a;}
ConfigB * MyContainer::GetConfigB(){return &config_b;}

但是,如果您想使用指针成员:

 MyContainer::MyContainer(int c = 1, double d = 2.1)
 :    pConfig_a (new ConfigA (c)), pConfig_b (new ConfigB (d))
{
}


ConfigA * MyContainer::GetConfigA(){return pConfig_a;}
ConfigB * MyContainer::GetConfigB(){return pConfig_b;}


 MyContainer::~MyContainer()
{
    delete pConfig_a;
    delete pConfig_b;
}
于 2013-01-02T13:39:50.117 回答
1
  1. 如果您ConfigA configA在标头中写入,则在分配容器类期间会自动分配 configA。所以你不必像下面这样初始化它:

    ConfigA config_a(1);
    this->config_a = config_a;
    

    相反,您可以执行以下操作:

    this->config_a->value = 1;
    
  2. 不需要写:

    ConfigA config_a(int c = 1);
    

    简而言之,提到int c = 1的是一个操作,它:

    • 在堆上为临时变量 c 分配空间(这也可以在进入方法时完成)
    • 为其赋值,这具有返回右侧值的副作用
    • 返回的右侧值应用于 ConfigA 构造函数。

    要理解这一点,请尝试以下操作:

    int a, b, c;
    c = (a = 2) + (b = 8);
    printf("a = %d, b = %d, c = %d\n", a, b, c);
    
  3. 如果要将配置传递给其他模块,可以选择以下解决方案之一:

    a) 接受配置作为参考(配置类必须派生自同一个基类):

    ConfigA & configA = dynamic_cast<ConfigA &>(container.get_config(ATYPE));
    

    在这种情况下,容器应通过以下方式返回配置:

    return this->configA;
    

    但标题应修改:

    Config & getConfig(TypeEnum type) { (...)
    

    b) 接受配置作为指针(同上)

    ConfigA * configA = dynamic_cast<ConfigA *>(container.get_config(ATYPE));
    

    在这种情况下,容器应通过以下方式返回配置:

    return &(this->configA);
    

最后,这是我会这样做的方式:

class ConfigA
{
private:
    int i;

public:
    int GetI() const { return i; }
    void SetI(int newI) { i = newI; }
};

class ConfigB
{
private:
    float f;

public:
    float GetF() const { return f; }
    void SetF(float newF) { f = newF; }
};

class Config
{
private:
    ConfigA configA;
    ConfigB configB;

public:
    ConfigA & GetConfigA() { return configA; }
    ConfigB & GetConfigB() { return configB; }
};

class AppContext
{
private:
    Config config;

public:
    Config & GetConfig() { return config; }
};

// Somewhere in the code

Config & config = context.GetConfig();
ConfigA & configA = config.GetConfigA();
configA.SetI(44);

const 正确性也值得一提,但我们将把它作为 OP 的练习;)

于 2013-01-02T13:23:22.667 回答