Say I have the following simple struct in C/C++:
struct Example {
int member_a;
int member_b;
}
Now, I have an object ex of it.
For the sake of redundancy and properly relating some members, I need to assign member_b using the value of member_a. Here, as I knew the name of this object, something like this worked for me:
struct Example ex = {
.member_a = 50,
.member_b = ex.member_a * 2 // Assigning member_b in terms of member_a.
}
The above assignment works as long as int member_a is kept above int member_b in the declaration of Example struct.
I have already tried using .member_b = member_a ... and .member_b = .member_a ..., both of which failed to identify the member_a in a struct object. .member_b = <same_object_name>.member_a only seems to work with the initial definition.
Note: This all has been tried on version C18
It was a way out in case of this single struct object, but what if I do not want to use object name or if in case I'm using anonymous (unnamed) struct object? Can something like pointers or some equivalent of this exists that is compatible with C for using the relation in an object (or better if possible in struct definition itself)? Even being able to call a value of member like .member_a within Example struct shall do.
Update: If C and C++ vary a lot, please focus on a C specific solution.
C/C++ are two completely different languages if they're used modernly where C++ can take advantage of classes and the this keyword. I would assume that you want to use structs in C++ for this exact question.
If you want to just have a direct relationship for example member b is twice member, then just set them equal in the original class so that it happens during compile time.
struct Example {
int member_a;
int member_b = 2 * member_a;
};
Otherwise you have to explicitly site which struct you are using when accessing ints within it. In this case a struct doesn't have any members that strictly pertain to it and the compiler doesn't know if there's going to be a value at member_a. If you wanted to use a class then you would just set it at anytime to itself, with a function or set statement.
class Bob {
public:
int member_a;
int member_b;
private:
int double_member_a(){
member_b = 2 * member_a;
return member_b
};
};
Bob bob;
bob.member_a = 1;
bob.member_b = bob.member_a; // or bob.doubleA();
Regardless of the method you would still be changing a struct or classes values depending on that exact instance of the object so you would always have to state which one, though if you were going through any x struct of class you would just put them into a vector and do a range based for loop and access one at anytime.
Related
How can I improve the structure of the code below?
I have a nested class. I want to access the parent class which is available as a global vector. The ugly part is when I store the index of the parent class in the child class. Can I do better?
vector<A> vec;
struct A
{
int val;
struct B
{
size_t id; // Index of the parent in the global vector. Doesn't look good!
void func()
{
cout << vec[id].val;
}
};
B b;
};
int main()
{
A a;
a.b.id = vec.size() - 1; // Also ugly!
vec.push_back(a);
}
Firstly you should not make use of global variables at all. It is quite bad practice, as any variable lacking access specification can be altered at any point by the program.
This is not so much of an issue with a small program such as this, but in bigger projects you might end up with some very nasty bugs if you were to continue using global variables.
Next, it makes sense to redefine this struct. There is no explicit rule, but in my opinion a struct should not really contain anything other than data members. It would instead be better to define a class, perhaps containing a struct similar to struct b if that is what you wanted. Personally however that is not how I would approach this problem.
Consider instead defining a class A, you might have a variable for "value". Then you might define a function that is passed a value that you want to assign that assigns a value to the "value" variable of that class.
Then within main you might instantiate a vector of "A"s, then set up a for loop(or some other kind of loop it is your choice after all). That for loop can then iterate however many times you tell it to. Per iteration you could instantiate an "A" object, initialise the value within the object, and then push the object onto the back of the vector of "A"s.
At any point within the scope of the main function you can iterate by another for loop through the vector of "A"s to access by index the the "A" object that is required, through which the value can also be accessed. So long as your for loop is set up to begin iterating from a count of 0, the index value for each element of the vector of "A"s will be the same as the the for loop's control variable at each iteration.
The approach that has been outlined is not the optimal solution, however as with all programming there are a number of solutions to your problem and it is up to you to find which is best. Given the context provided it makes sense not to confuse you further by overloading you with information but there are many ways to improve the potential solution outlined above.
Hopefully this answer shows you another path to the same destination, that perhaps is a little bit cleaner and more manageable. Furthermore as a first time responder I hope I have not made any mistakes myself(please let me know if I messed anything up here other readers)! Good luck with your programming!
I think you will need to pass a pointer of the enclosing class to the nested class to be able to use the enclosed class's non-static members.
See the PIMPL idiom for example here:
Why would one use nested classes in C++?
Could write classes like this:
#include <iostream>
#include <memory>
struct A
{
int val;
int getv() {return val;}
struct B
{
A * my_parent;
B(A * a) : my_parent(a) {}
void func()
{
std::cout << my_parent->val << std::endl;
}
};
std::unique_ptr<B> b;
A();
};
A::A() : b(new B(this)) {}
int main()
{
A a;
a.val = 1;
a.b->func();
}
I am wondering if there is any way to check if a given class contains a given member, except that given member's name is supplied as an std::string. Here is an example of the situation I am in:
class MyClass {
public:
int a;
int b;
int c;
void Handle_Class(std::string prop) {
if (this->prop) { //pseudo code of what I want to accomplish
//do stuff
};
};
} my_class;
int main() {
my_class.Handle_Class("a");
};
I know Handle_Class is not the best name for a function like this, but it is basically supposed to check if the class has a member called prop.
I have no idea how to actually do this though. Essentially I am trying to dynamically check if a class has a given member.
I have a lot of experience in Lua, and you could easily accomplish this in Lua (although Lua is not object oriented, you could accomplish this using tables)
local my_table = {a = 123; b = 456; c = 789};
local function Handle_Table(prop)
if my_table[prop] then
print("property "..prop.." exists inside my_table!");
end
end
I would appreciate any help.
Thanks
There is also a means of doing this at compile-time with templates, you cannot specify a dynamic string at runtime for the check, but consider:
How to detect whether there is a specific member variable in class?
So far I've read about structs, with and without pointers. My question is about a struct in combination with a class and main. What I learn from K&R and c++ sites is that a struct can't contain values. The values I want to assign to the members will be constants. In several posts I read that I should put the struct inside the class and even inside private. The setup I use was:
class C
{
struct something {const float m = 3} s;` //actually 12 members. Compiler doesn't accept values: "ISO C++ forbids initialization of member"
function foo(struct something s){ float m = s.m; <..do something..>}` //struct s actually used in several functions
};
int main(){C c;}
Then I created 2 structs, and letting the 2nd assign values to the members of the first, which I find ugly. But why did that get accepted by gcc? So how can I assign the values only once in a proper way since assigning values has to be done inside a function. BTW, I'm using Ubuntu gcc-4.6.1.
Thank you for an answer.
struct something {const float m = 3} s;` //actually 12 members. Compiler doesn't accept values: "ISO C++ forbids initialization of member"
to fix above do
struct something {
something (float const& f = 3) : m(f)
const float m;
} s;
The difference between struct and class in C++ is that structs default their members to public while classes default to private (same goes for inheritance). That's all there is to it.
Then, in C++03 const float m = 3; is not valid as a member declaration. You would need to declare a constructor for your struct:
struct something
{
const float m;
const float n;
something() : m(3), n(42) {}
} s;
Structs AND classes in C++ suffer from this problem. You can only declare a value in a class definition if the variable is static and shared among all the instances of the class. If your variable is const I think that may be a good choice.
A good solution for non-const variables is a simple one - assign the desired values to all the variables in the default constructor of your class or struct.
e.g
struct Something
{
float value;
Something():value(5.0f) {};
}
It appeared that this problem is quite common in our job.
We we are sending an int or enum value through the network, then we receive it we would like to create/call a particular object/function.
The most simply solution would be to use the switch statement, like below:
switch (value) {
case FANCY_TYPE_VALUE: return new FancyType();
}
It works fine, but we would have plenty of these switch blocks, and when we create new value and type, we would need to change all of them. It does seem right.
Other possibility would be to use the templates. But we cannot, since the value of enum is defined in runtime.
Is there any right design pattern for that, or any right approach?
It seems like a very general and common problem in every day coding...
Try a map:
struct Base { };
struct Der1 : Base { static Base * create() { return new Der1; } };
struct Der2 : Base { static Base * create() { return new Der2; } };
struct Der3 : Base { static Base * create() { return new Der3; } };
std::map<int, Base * (*)()> creators;
creators[12] = &Der1::create;
creators[29] = &Der2::create;
creators[85] = &Der3::create;
Base * p = creators[get_id_from_network()]();
(This is of course really crude; at the very least you'd have error checking, and a per-class self-registration scheme so you can't forget to register a class.)
You can actually do this with some template trickery:
#include <map>
template <typename Enum, typename Base>
class EnumFactory {
public:
static Base* create(Enum e) {
typename std::map<Enum,EnumFactory<Enum,Base>*>::const_iterator const it = lookup().find(e);
if (it == lookup().end())
return 0;
return it->second->create();
}
protected:
static std::map<Enum,EnumFactory<Enum,Base>*>& lookup() {
static std::map<Enum,EnumFactory<Enum,Base>*> l;
return l;
}
private:
virtual Base* create() = 0;
};
template <typename Enum, typename Base, typename Der>
class EnumFactoryImpl : public EnumFactory<Enum,Base> {
public:
EnumFactoryImpl(Enum key)
: position(this->lookup().insert(std::make_pair<Enum,EnumFactory<Enum,Base>*>(key,this)).first) {
}
~EnumFactoryImpl() {
this->lookup().erase(position);
}
private:
virtual Base* create() {
return new Der();
}
typename std::map<Enum,EnumFactory<Enum,Base>*>::iterator position;
};
This allows you to create a new derived object from a given enum, by saying
// will create a new `FancyType` object if `value` evaluates to `FANCY_TYPE_VALUE` at runtime
EnumFactory<MyEnum,MyBase>::create(value)
However, you have to have some EnumFactoryImpl objects, which could be static in some function or namespace.
namespace {
EnumFactoryImpl<MyEnum,MyBase,Derived1> const fi1(ENUM_VALUE_1);
EnumFactoryImpl<MyEnum,MyBase,Derived2> const fi2(ENUM_VALUE_2);
EnumFactoryImpl<MyEnum,MyBase,Derived3> const fi3(ENUM_VALUE_3);
EnumFactoryImpl<MyEnum,MyBase,FancyType> const fi1(FANCY_TYPE_VALUE); // your example
}
These lines are the single point where your source code maps enum values to derived types. So you have everything at the same location, and no redundancy (this eliminates the problem of forgetting to change it in some places, when adding new derived types).
One option is to maintain a dictionary of creators(which has the same interface) that can create a concrete type. Now the creation code will search in the dictionary for an int value (resulting from the enum sent from the client) and call the create method, which returns the concrete object via a base-class pointer.
The dictionary can be initialized at one place with the concrete creators corresponding to each possible enum values.
The problem here is that you have to extend this dictionary initialization code when you add a new type of object. A way to avoid is as following.
Let the creator look for a singleton factory instance and register itself in the constructor with the type enums(integers) with which it can create a concret object.
Create a DLL for one/set of creators and have a global instance of the creators.
The name of the DLL can be entered in a config file which is read by the factory in the initialization. The factory loads all the DLLs in this file and this results in the creation of the static objects which registers themselves with the factory.
Now the factory has the map of all the type enums which it can create with the concrete object creators.
The same object creator look-up mechanism is implemented to create the objects.
Now, the factory doesn't need to be extended at all since step 3,4 and 5 doesn't change for new objects introduced. Step 1 can be implemented in one place.
Only thing you need to do is to add a global object for each of the new concrete type which should be there since the C++ doesn't support reflection natively.
kogut, I don't propose this as an answer, but since you ask me to expand on my comment on your original question here's a very brief summary of what the .net environment gives you...
public enum MyEnum
{
[MyAttribute(typeof(ClassNone))]
None,
[MyAttribute(typeof(ClassOne))]
One,
[MyAttribute(typeof(ClassTwo))]
Two,
[MyAttribute(typeof(ClassThree))]
Three
}
So you have your basic enum One, Two, Three etc. which works just like....er....an enum!
But you also code up a class called MyAttribute (and in fact for more information in this area, just search for Attributes). But as you can see this allows you to say, at design time, that such-and-such an enum value is associated with such-and-such a class.
This information is stored in the enum's metadata (the value of a managed environment!) and can be interrogated at runtime (using Reflection). Needless to say this is very powerful, I've used this mechanism to systematically strip out loads of maps of the kind proposed in other answers to your question.
An example of the usefulness is this...at one client I worked with, the convention was to store statuses as strings in a database on the grounds that they would be more readable to a human who needed to run a table query. But this made no sense in the applications, where statuses were pushed through as enums. Take the above approach (with a string rather than a type) and this transform happened on a single line of code as data was read and written. Plus, of course, once you've defined MyAttribute it can be tagged onto any enum you like.
My language if choice these days is c# but this would also be good in (managed) c++.
I have a class, let's call it class A, that is performing a calculation which returns a value of int value, and another class in my system, class B needs to use int value for further calculations. My plan is to use a third class, class C, where the variable will be defined, to pass the variable between A and B, with these two just working from references to the int value in class C. My problem is I don't know how to reference a variable in another class without first instantiating some class or another, with the ensuing construction potentially overwriting int value.
Update: The code below outlines what I'm trying to achieve. I'm am trying to have variable
class A
{
public:
void calculation1()
};
void A::calculation1()
{
value = 10;
}
class B
{
public:
void calculation2();
};
void B::calculation2()
{
for (int count = 0; count < value; count ++)
{
// Do stuff here
}
}
class C
{
int value;
}
I believe you're not going in the right direction here. If I rephrase your problem description in pseudo-code, I get something like :
// The second calculation result depends on the result of the first one, so we
// provide it as a parameter.
int firstValue = calculationA();
int secondValue = calculationB(firstValue);
This is perfectly valid in itself : you just have to implement two free functions calculationA and calculationB and there is no need for classes of anything like it. Now, if you really want to put classes around this, you can.
What you need to understand is that classes interaction are a consequence of their respective responsibilities, not the opposite. For example, if the result of calculation1 has absolutely no utility beside being fed to calculation2, maybe the two functions shouldn't belong to different classes. Identify the responsibilities, try to express them as classes, and the interaction will appear naturally.
Why not just have a set function in class B, where you can set the value to what the calculation in A returns?