Reputation: 883
currently I switch from Java to C++ and this is giving me a hard time (but lots of new experience ^^). I'm writing some data-transfer-objects which contain configurations for my program. I've written some classes and now I want to have a class which behaves like a container.
Here's a header for the container:
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;
};
The configs have some data in it and are derived from another config-file.
And here is the C++-Source:
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;
}
There are several problems I think. But the main question for me is: How can I get those configs in this container to share it to other modules of my program? I have tried to make config_a to a pointer but I always get error-messages that these types won't match.
this->config_a = &config_a; //If ConfigA config_a; was ConfigA *config_a; instead
If you have another minute for me then please tell me if the getConfig
-Method could work like this.
And if there's another topic for this then please share. Thanks.
Upvotes: 0
Views: 629
Reputation: 25927
If you write ConfigA configA
in your header, the configA is automatically allocated during the allocation of the container class. So you don't have to initialize it like following:
ConfigA config_a(1);
this->config_a = config_a;
Instead, you can just do the following:
this->config_a->value = 1;
There is no need to write:
ConfigA config_a(int c = 1);
In short words, the mentioned int c = 1
is an operation, which:
To understand this, try the following:
int a, b, c;
c = (a = 2) + (b = 8);
printf("a = %d, b = %d, c = %d\n", a, b, c);
If you want to pass the configs to another modules, you can choose one of the following solutions:
a) Accept the configs as references (the config classes have to derive from the same base class):
ConfigA & configA = dynamic_cast<ConfigA &>(container.get_config(ATYPE));
In this case, container shall return the configs in the following way:
return this->configA;
But the header shall be modified:
Config & getConfig(TypeEnum type) { (...)
b) Accept the configs as pointers (same as above)
ConfigA * configA = dynamic_cast<ConfigA *>(container.get_config(ATYPE));
In this case, container shall return the configs in the following way:
return &(this->configA);
Finally, this is the way I would do it:
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);
The const-correctness is also worth mentioning, but we'll leave it as an exercise for the OP ;)
Upvotes: 1
Reputation: 1813
Your code:
ConfigA config_a(int c = 1);
Means a function prototype that returns ConfigA and takes an int with a default value of 1. But if you seperate the int declaration from the expression, it will change to something else:
int c;
ConfigA config_a(c = 1); // This is construction of a ConfigA object
I would write the constructor like this:
MyContainer::MyContainer(int c = 1, double d = 2.1)
: config_a (c), config_b (d) // Construct the members in the intialization line
{
}
If you want to share a pointer to these members, return a pointer like this:
ConfigA * MyContainer::GetConfigA(){return &config_a;}
ConfigB * MyContainer::GetConfigB(){return &config_b;}
But if you want to work with pointer members:
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;
}
Upvotes: 1