How to make an array of structs? [closed] - c++

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 };
}

Related

What happens if you put a struct within a struct?

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)

C++: virtual function calling parent [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 6 years ago.
#include <iostream>
using namespace std;
struct A
{
virtual int func(void) { return 0; }
};
struct B : A
{
int func(void) { return 1; }
};
int main()
{
A b = B();
cout << b.func() << endl;
}
I was expecting the output to be 1 but as most of you will know its 0.
what i want to achieve in my actual code is something along these lines.
struct A
{
virtual int operator() (int i);
};
struct B : A
{
int operator() (int i) { return i*2; }
};
struct C : A
{
int operator() (int i) { return i*3; }
};
struct x
{
A test;
};
So my container won't be able to tell before hand if it will hold a A, B or C, but should behave differently still.
Is there a way to achieve the functionality as I anticipated it work??
A b = B();: you're constructing an object of type A, using the assignment operator/copy constructor (through copy elision) from a B object, but seen as a reference to A (which explains why it compiles without errors)
This isn't polymorphism. b is still of type A. The link to B has been lost.
That would do it:
A *b = new B();
now
cout << b->func() << endl;
triggers polymorphism/virtual function and yields 1 as expected.
C++ virtual functions only works for references/pointers, which means indirections.
A b = B();
This creates an object of type A, not of type B. No indirection, therefor only the function in A is called.

Is it possible to access virtual methods of different ancestors of a polymorphic class through a single pointer?

I am building an interface, where it would be a little bit inconvenient to use separate variables to access individual interfaces, it would be great if somehow I could create a union of the two.
In a file:
struct A{
virtual int auu() { return 41; }
};
struct B{
virtual int boo() { return 43; }
};
In another file:
#include <path to A, B>
struct C : public A, public B{
int auu() { return 20; }
int boo() { return 22; }
};
And another file:
#include <declaration of A and B, but not C>
void doSth(A* a)
{
B * b = dynamic_cast<B*>(a);
/* I can only call auu with a */
a->auu();
/* I can only call boo with b */
b->boo;
/* Something like this would be ideal: */
<??? type> * C_interface = dynamic_interface_cast<B*>(a)
C_interface->auu();
C_interface->boo();
}
So is there to call both auu and boo through only one pointer variable and without the knowledge of C's implementation (not casting it to )? Also I'd like to avoid creating inheritance hierarchy that is NOT in connection with class C.
Probably the answer is no, however I'm curious if an idea like this has come up from the side of the language developers because to my primitive mind it's not a so far fetched idea.
EDIT:
In real, A and B are abstract. A is a Simulation object that has methods like size() and length(). B is an IO interface, implementing getters and setters, but it doesn't know about sizes so I have to use both interfaces in many calculations. C is a specialized Simulation that implements the former 2.
EDIT:
I rewrote the question, maybe it actually makes sense now.
I'll ilustrate the point I made in my comment. It's perfectly legal to cast between siblings, as long as the actual object is derived from both.
#include<iostream>
using namespace std;
struct A{
virtual int auu() { return 41; }
};
struct B{
virtual int boo() { return 43; }
};
struct C : public A, public B{
int auu() { return 20; }
int boo() { return 22; }
};
void take_B(B* bp)
{
cout << bp->boo() << endl; // expected
cout << "(The base class would say "
<< bp->B::boo() << ")" << endl; // base class implementation
A *ap = dynamic_cast<A*>(bp);
if(!ap)
{
cerr << "weird, this cast should be possible!" << endl;
}
else
{
cout << ap->auu() << endl; // should work
cout << "(The base class would say "
<< ap->A::auu() << ")" << endl; // base class implementation
}
}
int main()
{
C c;
take_B(&c);
cout << endl << "... and again:" << endl;
// just to clarify: The actual pointer type is irrelevant.
B *bp = &c;
take_B(bp);
return 0;
}

C++ inheritance, calling the given classes function instead of its parent?

Really bad title, couldn't think of how to word it, sorry.
So say I had the following code:
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
int getSize() {
return 32;
}
}
void doStuff(A a) {
std::cout << a.getSize() << std::endl;
}
int main() {
B b;
doStuff(b);
}
It would print out 0, however I want it to print out 32. In other words, I want to pass it the class and it prints out that classes function, so I could create a class C, where the size is 64, and if I pass that C instance to the doStuff function, I want it to print 64.
Is there any way I can do this in C++, would I have to use templates or some fancy C++ feature I don't know about?
A one-byte patch:
void doStuff(A &a) {
std::cout << a.getSize() << std::endl;
}
Your version takes the argument by value, which means that the function makes a copy of b (a copy which is an A) and then calls the copy's getSize(). In this version, the function takes the argument by reference, and calls b's own getSize(), which is B::getSize().
You should use pointers, or even better: smart pointers! That way, the function of the runtime type gets called. It's a basic example of polymorhpism. If you want to avoid pointers, Beta's slicing approach is equally valid.
#include <iostream>
#include <memory>
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
virtual int getSize() {
return 32;
}
}
void doStuff(std::shared_ptr<A> a) {
std::cout << a->getSize() << std::endl;
}
int main() {
std::shared_ptr<A> b(new B());
doStuff(b); // Will output '32'.
}
This should correctly call the function as implemented by B.
Slicing the object is one approach, and in addition I think you're asking for, I think, a pretty straightforward use of polymorphism in C++. http://www.cplusplus.com/doc/tutorial/polymorphism/
That's almost immediately applicable, just call your class A Shape, and B and C could be Square and Triangle. Your DoStuff function could take a pointer to a Shape, then you can pass it a triangle or a square, and when you deference the Shape in the function, it will call the correct function.
So you'd have (also you need to make the members public, I think):
class A {
public:
virtual int getSize() {
return 0;
}
};
class B : public A {
public:
int getSize() {
return 32;
}
};
void doStuff(A* a) {
std::cout << a->getSize() << std::endl;
}
int main() {
B b;
doStuff(&b);
}

CRTP / Macros / Avoid casting pointer of derived class

Lately I've been working in some project and the thing is that we've encountered a situation in which we need to be able to do stuff like this.
#define TYPED(Type) \
virtual Type *typedThis() const { return (Type*) this; }
class A {
public:
TYPED(A)
virtual void describe() { std::cout << "I am type A\n"; }
static int x;
};
int A::x = 1;
class B : public A {
public:
TYPED(B)
virtual void describe() { std::cout << "I am type B\n"; }
static int x;
};
int B::x = 2;
int
main(int argc, char** argv)
{
B* b = new B();
A* b2 = b;
b->describe();
b2->describe();
std::cout << b->typedThis()->x << std::endl;
std::cout << b2->typedThis()->x << std::endl; // AQUI DEBERIA DAR 2 !! :c
}
This is of course just a toy example. The basic idea of what we would like to do is to define a function typedThis() who does the casting of the pointer into the correct type and then access to the correct variable x, and printing out 2 instead of 1.
However, the output is the following:
I am type B
I am type B
2
1 //Here should also be 2
What I find really interesting is that the virtual method describe() seems to be working the way we want. Therefore, I could infer that the method typedThis() is also working the way we would like to. But if so, why does C++ see this pointer as an A* instead of an B*. If C++ saw this pointer like a B* then it would have used the correct variable x. Can someone explain this to me?
I tried using CRTP, however I don't feel like this would make things easier, because in the project we will be using a lot (A LOT) of different classes who derive between them constantly, I saw some articles of how to use CRTP when having multiple inheritance, however they are really messy and hard to integrate with what we have so far.
I removed all distractions from the example:
class A {
public:
virtual A *typedThis() const { return (A*) this; }
static int x = 1;
};
class B : public A {
public:
virtual B *typedThis() const { return (B*) this; }
static int x = 2;
};
int main()
{
B* b1 = new B;
A* b2 = b1;
std::cout << b1->typedThis()->x << "\n";
std::cout << b2->typedThis()->x << "\n";
}
typedThis doesn't do anything.
b1->typedThis() returns a B* which points to a B.
Likewise, b1 itself is a B* which points to a B.
b2->typedThis() returns an A* which points to a B.
Likewise, b2 itself is an A* which points to a B.
So b1->typedThis() is the same as b1 and b2->typedThis() is the same as b2, and the last two lines of the example are equivalent to the following:
std::cout << b1->x << "\n";
std::cout << b2->x << "\n";
Also take note that your C-style casts discard the const qualifiers of the objects.