struct b;
struct a {
int argx;
int argy;
b structB;
};
struct b {
int argw;
int argz;
a structA;
};
int main() {
a structA;
std::cout >> structA.argx >> std::endl;
// Couldn't you do std::cout >> structA.structB.structA.structB... ;
}
What will happen? Will there be recursive memory usage?
I was wondering this because I was doing something like this in my code.
That's not possible in C and C++. You can't use the struct b in the struct a before it is defined. Even if you use forward declarations you can only use a pointer or reference. You can't create an instance of an incomplete type.
You can't compile this code.
You can create a pointer to an incomplete type instead:
struct b;
struct a {
int argx = 1;
int argy;
b *structB;
};
struct b {
int argw = 2;
int argz;
a *structA;
};
int main() {
a structA;
b structB;
structA.structB = &structB;
structB.structA = &structA;
std::cout >> structA.argx >> '\n';
std::cout >> structA.structB->argw >> '\n';
std::cout >> structA.structB->structA->argx >> '\n';
}
Should be fine. I've used structs in other structs before and never noticed a difference. Then again I wasn't profiling performance.
I wouldn't have both structs include each other though. I feel like that would be bad.
Edit: As #Thomas Sablik pointed out you can't use struct b in a, because it wasn't defined before.
I was talking about using a in b not the other way around. (when I've used structs in structs before)
Related
I was messing around with structs and noticed that of the following two examples, only one worked. Here they are:
struct Test
{
char *name;
int age;
};
Test p1 = { "hi", 5 };
//works
struct Test
{
char *name;
int age;
}p1;
p1 = { "hi", 5 };
//error
How come the first one compiles and the second one doesn't? Isn't p1 an object of Test either way? Thanks.
In the first example you are initializing a struct with two values in a "brace initialization." There is no support in C++ (or C) for assigning to a struct using a brace-enclosed list.
You could, however, create a new struct using brace initialization, then assign it to the old struct (p). C++ (and C) does support assignment of one struct to another of the same type.
For example, in C++11:
p1 = Test{ "hi", 5 };
The following does work with C++11:
(Compile with g++ -std=c++11 init.cpp)
#include <iostream>
struct XXX {
int a;
const char *b;
};
int main() {
XXX x;
x = XXX{1, "abc"};
// or later...
x = XXX{2, "def"};
std::cout << x.b << std::endl;
return 0;
}
I really want to do the following:
(sorry about syntax, I have no idea how this is done)
struct Data {
int var = 5;
} data;
struct Data2 {
var;
} data2;
data2.var = data;
cout << data2.var.var; //prints 5
Basically I want to have a dynamic struct variable in a struct that can be given any struct as value and access it through the mains struct.
Please be nice. I really don't know how to explain it better and I really want to do this and been reading a lot yet haven't found any methods to do this.
Ps.
I DON'T want to do the following:
struct Data {
int var = 0;
} data;
struct Data2 {
data;
} data2;
I want it to be dynamic, that is, that I can change it any time during the program. Thank you.
Conceptually, you may (?) be asking about references:
#include <iostream>
int main() {
int x = 10;
int & xref = x;
std::cout << xref << "\n";
x = 20;
std::cout << xref << "\n";
}
That will print:
10
20
Underlying a reference is essentially a pointer, but it is one which can never be null...and notationally you don't have to "dereference" it. Were you using pointers, the above would look like:
#include <iostream>
int main() {
int x = 10;
int * xptr = &x;
std::cout << *xptr << "\n";
x = 20;
std::cout << *xptr << "\n";
}
Here they are applied to your example with minimal changes:
#include <iostream>
struct Data {
int var;
};
struct Data2 {
Data & var;
};
int main()
{
Data data = {5};
Data2 data2 {data};
std::cout << data2.var.var << "\n";
data.var = 10;
std::cout << data2.var.var << "\n";
return 0;
}
Odds are "this isn't what you actually want" (you shouldn't usually be exposing member variables, much less member variables that are references to other variables). And they shouldn't be all named var. Etc.
Still, references are an integral part of the language and worth learning about.
(Note: for brevity, you may omit the return 0;...only from main. That's assumed, and legal in the standard; and you may omit its arguments. But you must return an int.)
You can use void pointer like this:
#include <iostream>
using namespace std;
struct Data
{
int var;
}data;
struct Data2
{
void *var;
}data2;
int main()
{
data.var = 5;
data2.var = &data;
cout<<((Data *)data2.var)->var<<endl;
return 0;
}
But it is not safe because somtimes you can't make sure that other struct has member called var which may cause unexpected result.
Basically I want to have a dynamic struct variable in a struct that
can be given any struct as value and access it through the mains
struct.
You can emulate the effect of dynamic typing by using polymorphism. The following is a test example for your case.
#include <iostream>
using namespace std;
struct BaseDataStruct
{
virtual int get_data() = 0;
};
struct Data : BaseDataStruct
{
int var = 5;
virtual int get_data() { return var;}
} data;
struct Data2 {
BaseDataStruct* var;
} data2;
int main()
{
data2.var = &data;
cout<<data2.var->get_data();
return 0;
}
By using BaseDataStruct as an interface base class for all the structs which Data2::var is expected to point to you can achieve the "dynamic typing" behavior you are trying to get.
Note: I changed the Data2::var a to pointer to avoid object slicing. You will need to jump through many hoops to avoid that if you want to have it by value.
TL/DR: C++ is statically typed, so what you want to do is against the spirit of thr language. However, if you really have to you can use void* in C and boost::any in C++
Now a bit more about void* (to know more about boost::any refer to its documentation).
void* is a pointer that holds a raw address in memory. This value beyond this address could be everything: float, int or your struct. Here is the usage example.
struct Data {
int var = 5;
};
struct Data2 {
void* var;
};
int main() {
Data data;
Data2 data2;
data2.var = (void*)(&data);
cout << ((struct Data*)data2.var)->var << endl;
}
If the concept of pointers is new for you you can read about it here. Void pointers are explained there as well.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I would like to know if I can make an array of structs, then use it in a foreach loop.
struct A { int a; };
struct B { int b; };
struct C { float c; };
And then:
int main()
{
A a; B b; C c;
//Here I want to make an array of a, b and c,
//then use it in for loop with the ints and floats.
}`
You can't safely make an array of unrelated types in C++.
If you have the need to put objects together in a container, then they are probably somewhat related : you should think about adding a common base class to A, B and C, and then manipulate an array (or vector...) of (smart) base class pointers.
However, think about the possible alternative of defining a type encapsulating your struct, instead of declaring this "array" :
struct T {
A obj1;
B obj2;
C obj3;
};
Note :
If you really need type erasure, then boost::any or boost::variant are very handy to encapsulate objects or any type.
Of course you can, but you cannot make an array of unrelated types/structs without using external libraries:
#include <iostream>
struct Person
{
std::string name;
int age;
std::string job;
};
int main()
{
Person people[10];
//I am a normal one.
for(int i=0; i<10; ++i)
{
people[i].name = "usar";
people[i].age = i;
people[i].job = "Astronaut";
}
//foreach loop
for(Person p: people)
{
std::cout << "Name: "<< p.name << "\n";
std::cout << "Age: "<< p.age << "\n";
std::cout << "Job: "<< p.job << "\n";
}
return 0;
}
Yes Just create it just as other types. Assume that we have a struct of Car
struct Car
{
int engine;
string brandName;
};
You can create it like
Car list[2]={{3000, "BMW"},{2200, "Mercedes-Benz"}};
or just
Car list[2];
If you want to have "array" of different types, it is technically possible in C++ though not simple. At least not for novice C++ programmers. First of all you would need to use non trivial data type like boost::variant or std::tuple, second - accessing that data will require template metaprogramming, which is also not easy for beginners. But most probably your problem has simpler solution and can be solved more easily, you are just looking into wrong direction.
struct Base
{
virtual ~Base(){}
virtual int GetInt()
{
throw "Not implemented";
return 0;
}
virtual float GetFloat()
{
throw "Not implemented";
return 0.0f;
};
};
struct A : public Base
{
int a;
virtual int GetInt()
{
return a;
}
};
struct B : public Base
{
int b;
virtual int GetInt()
{
return b;
}
};
struct C : public Base
{
float c;
virtual float GetFloat()
{
return c;
}
};
int main()
{
A a; B b; C c;
Base* array[ 3 ] = { &a, &b, &c };
}
I tried asking before but I wasn't very clear so I'm re-asking it.
I want to have a variable that depends on the value of another variable, like b in this example:
int main(){
int a;
dependent int b=a+1; //I'm just making this up
a=3;
cout << b; //prints 4
a=4;
cout << b; //prints 5
}
Of course, this does not exist in C++, but this is what I want.
So instead I tried making a function:
int main(){
int a;
int b(){ return a+1; } //error
a=3;
cout << b(); //would print 4 if C++ allowed nested functions
a=4;
cout << b(); //would print 5 if C++ allowed nested functions
}
The above doesn't work because C++ doesn't allow nested functions.
I can only make functions outside of main(), like this:
int b(){
return a+1; //doesn't work because a is not in scope
}
int main(){
int a;
a=3;
cout << b();
a=4;
cout << b();
}
But this does not work because a is not in the same scope as b(), so I would have to pass a as a parameter and I don't want to do that.
Are there any tricks to get something similar to a dependent variable working in C++?
What you need is a closure. If you can use C++ 0x features, you are in luck. Otherwise, you can define one manually:
#include <iostream>
using namespace std;
struct B
{
const int & a;
B(const int & a) : a(a) {}
// variable syntax (Sean Farell's idea)
operator int () const { return a + 1; }
// function syntax
int operator () () const { return a + 1; }
};
int main()
{
int a;
B b(a);
a = 3;
cout << b << '\n'; // variable syntax
a = 4;
cout << b() << '\n'; // function syntax
}
You can also define B inside main, but some compilers would not like it.
The C++ 0x lambda syntax looks like this:
auto b = [&]() { return a + 1; }
The [&] means that the lambda captures local variables by reference.
If you're using C++0x (GCC 4.5+, Visual C++ 2010), you can use lambdas:
int a = 5;
auto b = [&a]{ return a + 1; };
std::cout << b() << std::endl;
Depending on what you're doing, though, there are probably cleaner solutions - possibly some variation of the classic "method that takes in 'a' and returns 'b'"
You could define a class that had a member a, and then a function b() that returned the value of a+1. A basic implementation would be something like:
class Dependent {
public:
Dependent(void) { m_value = 0; }
void set(int value) { m_value = value; }
int b(void) { return(m_value + 1); }
private:
int m_value;
};
int main(){
Dependent a;
a.set(3);
cout << a.b();
a.set(4);
cout << a.b();
}
You could add operator overloading as appropriate to make it work more like normal integers if you so desired.
This is possible if you use lambda functions (c++0x), because they can capture local variables.
Example:
int main()
{
int a;
auto f = [&] () -> int { return a + 1; };
a = 3;
std::cout << f() << std::endl;
a = 4;
std::cout << f() << std::endl;
return 0;
}
Result:
4
5
(See http://ideone.com/MlzX7 for proof)
A simple approach is to use pre-processor macros, nothing C++ specific about it though:
#define b ((a)+1)
int main(){
int a;
a=3;
cout << b;
a=4;
cout << b;
}
#undef b
Are you OK using C++0x ? if yes,
int main()
{
int a = 10;
auto b = [&a]() -> int { return a + 1; };
cout << b() << endl;
}
Since, it is not tagged with c++0x, you can use nested classes instead of nested functions. This column from Herb sutter would help you for existing c++. http://www.gotw.ca/gotw/058.htm
The above doesn't work because C++ doesn't allow nested functions.
You can simulate that using nested structure. In C++0x you can make use of lambda function, which provides the same means of function inside function.
Define a class called LinkedInt or something that behaves like an int, but has a RelatedTo relationship on itself and an additional member that is a function pointer to the function to evaluate when computing the integer's value. Pretty straightforward. Let me know if you need some pointers on the coding.
The short answer is that OOP is more than enough to bury this problem.
I want to have a variable that depends on the value of another
variable, like b in this example:
I see you just need a reference variable:
int a;
int &b =a;
a=10;
cout << b; // 10
Why C++0x lambdas do come for this, I dont understand.
I need to have several instances of a union as class variables, so how can I create a union instance in the heap? thank you
The same as creating any other object:
union MyUnion
{
unsigned char charValue[5];
unsigned int intValue;
};
MyUnion *myUnion = new MyUnion;
Your union is now on the heap. Note that a union is the size of it's largest data member.
My C++ is a bit rusty, but:
my_union_type *my_union = new my_union_type;
...
delete my_union;
Same as a struct :) You can use malloc() and do it the C way, or new for the C++ way. The secret is that structs, unions and classes are related; a struct is just a class (usually) without methods. There's more clarification in the following comments, should you care.
Use the new operator.
I'm not sure where you want to head with this. A union is a user-defined data or class type that, at any given time, contains only one object from its list of members. So starting from this, if you have a union defined like this:
union DataType
{
char ch;
integer i;
float f;
double d;
};
You can then use DataType as a type to define members in a class or as a type to define variables on the stack, just like regular types, struct or classes you define.
Use the new operator:
#include <iostream>
union u {
int a;
char b;
float c;
};
class c {
public:
c() { u1 = new u; u2 = new u; u3 = new u; }
~c() { delete u1; delete u2; delete u3; }
u *u1;
u *u2;
u *u3;
};
int main()
{
c *p = new c;
p->u1->a = 1;
p->u2->b = '0' + 2;
p->u3->c = 3.3;
std::cout << p->u1->a << '\n'
<< p->u2->b << '\n'
<< p->u3->c << std::endl;
delete c;
return 0;
}