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();
}
Related
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.
Given the class:
class A {
Public:
void foo() {
static int i;
i++;
}
};
How would you change it to prevent i from changing between instances following this example:
A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 1
o3.foo(); // i = 1
o1.foo(); // i = 2
i.e. allocate memory for i on every instance.
EDIT:
Yes, you can add i as an instance variable, but what if you need these counters in various (independent) functions ? I am looking to limit the scope of the variable only to the function ("in member functions"). It would seem awkward to add variables such as i, c, counter, counter_2 to the class if you need various counters, would it not ?
class A
{
public:
int i = 0;
void foo(){
++i;
}
};
is the normal way: i is now a member variable of the class. Clearly you don't want to use static.
In circumstances where declaring data members become costly(need for sparse members that are not used so often), An instance indepent collection - normally an associative one - may come in handy. Knowing nothing more about the OP's intention, std::map family of classes can be used as first speculation. We need to have one counter per visited object in A::foo, but not for unvisited instances(i.e. A instances not calling A::foo). This was the the simplest first solution I came up with:
void A::foo(){
static std::map<A*,std::size_t> i;
++i[this];
//...
};
Upon call to std::map::operator[] on an object not in the map, the associated value is default constructed in a memory location already zeroed by the allocator( in short words 1st-timers are automatically initialized to 0).
PROBLEM:
I want to set up a system of elements, while at the same time keeping pairs of these elements that I want to access and modify easily (add more).
At the same time, I want to keep the complexity to a minimum, and not implement everything in one class.
I decided to store the indices to the pairs using a struct, which can handle a large amount of the complexity of calculations among B's.
class A {
class B_pair {
int idx_of_B[2];
public:
B get_B_value_1(); // how to access B's?
B get_B_value_2();
// a lot more member functions
};
public:
std::vector<B> B_values;
std::vector<B_pair> special_B_pairs;
// a lot more stuff
};
However, I have the problem that I cannot access the B values from within the B_pair class.
FAILED SOLUTION 1
class A {
A() { B_pair::outer = this; }
class B_pair {
static A *outer;
void init_outer(A *o);
};
}
I used a static member because I have a lot of B_pair objects, and the extra memory of a pointer/reference in each is significant.
This works fine. However, if I have more than one A objects at the same time, then it is problematic, as the outer pointer ends up pointing at the last created A object.
FAILED SOLUTION 2
Another approach I took was storing pointers.
class A {
class B_pair {
B *items[2];
};
std::list<B> B_values; // I need random access iterators!!
};
However, this means that I need to use more inefficient data structures than std::vector, which invalidates its iterators when it expands.
QUESTION
How could I access the members of the outer class A from the inner class B, or something similar to make this work? Ideally, I would like something similar to the first solution, but with one instance of A *outer for each A object.
Note that THIS IS POSSIBLE IN JAVA!!
P.S. At the moment I am using the Singleton design pattern, and kept the static pointer. Not a big fan of this solution.
I have friend function 'fun()' of a class A. fun takes reference of object of type A. let's say objname is 'obj'
Inside fun() friend function, in order to access elements of class A, obj.member is required. Because there are large number of members i want to skip this 'obj.member' and saying 'member' should refer to the object passed.
Is there a way by which this can be achieved? say declaring something on the top of the function because of which i need not say 'obj.something' again and again, and only 'something' will be fine.
My sample code is below.
#include<iostream>
using namespace std;
class A{
private:
int x;
char c;
string s;
public:
A(int x, char c, string s) : x(x), c(c), s(s){};
friend void fun(A& obj);
};
void fun(A &obj){
//is there any thing here i can use on top so that i don't need to refer obj.x or obj.c or obj.s ...so on?
// anything like "using" ... which can tell which ?
//In that way i want to similulate hidden this pointer concept.
int x = obj.x;
char c = obj.c;
string s = obj.s;
//.....similarly accessing other elements of obj
cout<<x<<" "<<c<<" "<<s<<" "<<endl;
}
int main()
{
A obj(20,'Z',"friend");
fun(obj);
return 0;
}
The short answer is that you can't - or the things that seem to work for this are really bad ideas.
In a friend (or any non-member) function, all references to an object (accessing data members, calling non-static member functions) require using the obj.<whatever> syntax.
Really, your question reflects a sense of false economy - sort of like Nero fiddling on the roof while most of Rome burned down. The additional typing of obj. on a few statements is insignificant, and techniques to reduce the typing burden make your code less clear, harder to understand, and more confusing for future developers - including, more than likely, yourself.
You could try doing something with a macro
#define X obj.
char c = X c;
but that doesn't save on typing, and gives code that will be confusing to humble C++ programmers (including yourself in future). So it is not a good idea.
You could also try doing something like
void fun(A &obj)
{
obj.fun(); // call a member function that does everything needed
}
but that is sort of pointless in practice - it is still necessary to define the member function and, if you have it, there is little need for the non-member version.
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?