If I were to make a struct, say:
struct FOO{
int x, y, z, a, b, c;
}
int main(){
FOO foo = {1, 2, 3, 4, 5, 6};
return 0;
}
Would there be anyway to create a pointer that can access FOO's integer members?
Maybe by making pointer that points to foo and then somehow modifying it to increment in integers?
I know that if I were to make FOO a class instead with a method that returns a pointer to the first int, then I could cycle though the members with ++ or [i](in a for loop). But I want to know if I can access structure members simply by knowing the address of the struct (assuming I have a good understanding of how to navigate said struct)
Any insight would be much appreciated.
Thanks!
You can overload operator[] for the struct:
struct bar // ALL_UPPERCASE is for macros!
{
int a, b, c, d, e, f;
int operator[](size_t i) const
{
switch(i)
{
case 0: return a;
case 1: return b;
case 2: return c;
case 3: return d;
case 4: return e;
case 5: return f;
default: assert(false);
}
}
};
Just a thought and this might not work, but you could try doing a pointer to the foo struct and then shifting the pointer by the size of an int for each element. So something like:
int * ptr= & foo;
ptr++;
If I'm remembering my hardware design class well enough a struct is actually really similar to an array in memory it can just have variable sized blocks of memory for each of its indices.
struct FOO{
int x, y, z, a, b, c;
} __attribute__ ((packed))
FOO foo;
int *i = &foo;
In this case, the attribute ((packed)) eliminates the problem created by padding, since it get's rid of it. Afterwards incrementing i, grantees that it will be in the next element of the struct.
It's pretty straightforward:
Foo foo = { 1, 2, 3, 4, 5, 6 };
int* pfoo = &foo.x;
int structMembers = sizeof(Foo) / sizeof(int);
for (int i = 0; i < structMembers; i++)
{
cout << pfoo[i] << endl;
}
There's no difference between a struct and class aside from default access modifier (private in structs, public in classes). Thus whatever you can do with classes, you can do with structs.
As I understood you need this: https://en.cppreference.com/w/cpp/utility/functional/mem_fn
if you need own implementation take this:
#include <iostream>
struct Foo
{
int a = 1;
char b = 'a';
};
template<typename Struct, typename var_type>
const var_type member_get( Struct& obj, var_type Struct::* mem_var ) { return
obj.*mem_var; }
int main()
{
Foo x;
std::cout << member_get( x, &Foo::a ) << std::endl;
std::cout << member_get( x, &Foo::b ) << std::endl;
return 0;
}
Related
I am trying to initialise class object (which has constant members) with certain values and certain address. I understand that this is because members are constant but I need them to be constant. I tried to find solution but with no success.
So the question is: is there some "easy" way to do it?
class ints{
public:
const int a;
const int b;
ints(int a, int b);
};
ints::ints(int a, int b) :
a{a},
b{b}
{}
int main() {
auto ptr = (ints*)malloc(sizeof(ints));
ints values{1, 2};
// all wrong
// *ptr = ints copy{values};
// &values = ptr;
// *ptr = values;
std::cout << ptr->a; //ptr->a should be equal to 1
}
You can create an object at a specific address using placement-new:
extern void* some_address;
int main()
{
ints* ptr = new(some_address) ints{1, 2};
std::cout << ptr->a;
}
I have a struct Foo;
typedef struct {
int bar;
char baz;
} Foo;
Suppose I then declare an array of Foo as;
Foo* arr = new Foo[300];
And proceed to initialize every member with a loop. I would like very much to be able to get an array of all members bar;
int* barr_arr = ...
What is the most efficient way to do this? Is there some way to exploit the memory layout such that I need not loop over the entire Foo array?
Since we know the memory layout in advance could we exploit the fact that we know the address of every member if we're clever about alignment?
What is the most efficient way to do this? Is there some way to exploit the memory layout such that I need not loop over the entire Foo array?
I don't think there is away to do that without looping. You can simplify your code by using std::transform but std::transform does loop.
Also, I would recommend using std::vector instead of allocating an array using new.
std::vector<Foo> arr(300);
....
std::vector<int> bArr(arr.size());
std::transform(arr.begin(), arr.end(), bArr.begin(), [] -> (Foo const& f) { return f.bar; });
When you are initializing the first array, you can grab a pointer to the field inside each element and store that in a separate array.
struct Foo
{
int bar;
float baz;
};
const int SIZE = 5;
Foo foos[SIZE];
int *bars[SIZE];
for(int c = 0; c < SIZE; c++) {
foos[c].bar = c;
foos[c].baz = c;
bars[c] = &foos[c].bar; // Grab pointer to field
}
for(int c = 0; c < SIZE; c++) {
std::cout << "Bar Value: " << *bars[c] << std::endl;
}
If Foos typically exist in arrays, and corresponding arrays of bars and bazs often need to be accessed, I would suggest redesigning your data structures to better suit your problem. Obviously, we're not reading the code that inspired this question, but given the information provided, I might suggest something like:
struct FooArray {
int* bars;
char* bazes;
size_t n_elements;
};
This removes the need to allocate a new buffer for the bar array, which, depending on how many Foos are being processed, might entail significant memory savings.
I would also note that, if you're not working at a low level and don't actually need an int* but can do with a std::vector<int>, then #R Sahu's answer is likely a more appropriate solution.
The goal drives the design.
If your main use is to pass all bar members in a row, same for baz members, then create separate containers:
std::vector<int> bar;
std::vector<char> baz;
Then passing bar as an array is straightforward: just use bar.data().
If you add a constructor to your Foo that takes the size of array, you could have only one object of Foo. You can then make it that you can access either the whole vector data or individual elements with subscript:
#include <iostream>
#include <vector>
#include <memory>
struct Foo
{
std::vector<int> bars;
std::vector<char> bazs;
std::size_t size;
Foo(size_t size, int bar = 0, char baz = 0) :
bars(size, bar), bazs(size, baz), size{size}
{
}
auto operator[](size_t n)
{
// if (n >= size) ...
struct
{
int &bar;
char &baz;
} temp{ bars[n], bazs[n] };
return temp;
}
};
int main()
{
Foo arr(30, 100, 'a'); // 30 items
std::cout << arr[29].bar << std::endl;
std::cout << arr[29].baz << std::endl;
std::cout << arr.bars[29] << std::endl;
std::cout << arr.bazs[29] << std::endl;
std::unique_ptr<Foo> arr2 = std::make_unique<Foo>(25, 10, 'b'); // 25 items
std::cout << arr2->operator[](15).bar << std::endl;
std::cout << arr2->operator[](15).baz << std::endl;
arr2->bars[15] = 11;
std::cout << arr2->bars[15] << std::endl;
arr2->bazs[15] = 'c';
std::cout << arr2->bazs[15] << std::endl;
return 0;
}
Demo: https://ideone.com/TiVwOT
100
a
100
a
10
b
11
c
I have an array of pointers declared as a class member like this:
class Bar
{
private:
static constexpr int SIZE = 10;
Foo* m[SIZE];
}
In one of my class methods, I would like to return a pointer (or preferably, a reference) to this array. The array has a known size at compile time, but I am keeping track of how many items I have put in there (it is a buffer of stuff).
What is the best way to return a reference to this array in C++11 ?
Here are the things I have tried:
GetArray(Foo* &f[], unsigned &size) const
I like the syntax because it makes it clear that the reference value is an array of pointers, but this gives a compiler error: Declared as array of references of type Foo*
GetArray(Foo** &f, unsigned &size) const
{
f = m;
size = mSize;
}
Gives me: Error: assigning to Foo **' from incompatible type Foo *const[10]. Casting mFoo to (Foo**) alleviates the error, but IMHO, this is not elegant.
Nobody posted an answer using std::array yet, it is a very simple replacement:
class Bar
{
std::array<Foo *, 10> m;
public:
std::array<Foo *, 10> & getArray() { return m; }
std::array<Foo *, 10> const & getArray() const { return m; }
};
This seems to me a lot simpler than the hoops you have to jump through to use your C-style array version.
To avoid code duplication you could typedef std::array<Foo *, 10> FooArray; .
The technique of having both a const and a non-const implementation is a common pattern for accessor functions which return a reference or a pointer. (It's not required if your accessor returns by value, of course).
I would seek to use a std::array or a std::vector in most cases. If you are determined to use a raw array then you could go this way with it:
typedef int Foo;
typedef Foo* (&FooPtrArrayRef)[10]; // to make the syntax less hairy
class Bar
{
private:
Foo* m[10];
public:
// First way without using typedef
Foo* (&getArray())[10]
{
return m;
}
// Nicer looking way with a typedef
FooPtrArrayRef getArrayByRef()
{
return m;
}
};
int main()
{
Bar b;
Foo* (&array)[10] = b.getArray();
std::cout << (sizeof(array) / sizeof(Foo*)) << '\n';
// Alternative using "size deduction"
Foo* (&array2)[sizeof(b.getArray()) / sizeof(Foo*)] = b.getArray();
std::cout << (sizeof(array2) / sizeof(Foo*)) << '\n';
// MUCH nicer using the typedef
FooPtrArrayRef array3 = b.getArrayByRef();
std::cout << (sizeof(array3) / sizeof(Foo*)) << '\n';
}
The syntax is pretty obscure though.
The benefits of this is approach is that it retains the full type information of the array you are passing by reference. The obscure syntax is necessary to avoid the type collapsing to a Foo**. By retaining the full type of the array you retain the ability to know its size at compile time using the sizeof() operator.
here's another approach that returns the array reference and the current size as a tuple:
#include <tuple>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
struct Foo {};
using FooBuffer = Foo*[10];
class Bar
{
public:
Bar()
: _m { nullptr }
{
_m[0] = new Foo;
_m[1] = new Foo;
_items = 2;
}
~Bar() {
for(auto fp : _m)
delete fp;
}
std::tuple<FooBuffer&, size_t> getInfo() {
return std::make_tuple(std::ref(_m), _items);
}
private:
Foo* _m[10];
size_t _items;
};
int main() {
Bar b;
auto info = b.getInfo();
FooBuffer& buf = std::get<0>(info);
size_t items = std::get<1>(info);
for(Foo** p = buf ; p != buf + items ; ++p) {
std::cout << "Foo at " << std::hex << *p << std::endl;
}
return 0;
}
I just saw a post in which I found something I never saw before, in short here it is:
class A {
public:
int _x;
};
void foo(A *a_ptr, int *m_ptr)
{
cout << (*a_ptr).*m_ptr << endl; // here
}
int main()
{
A a;
a._x = 10;
foo(&a, &A::_x); // and here
}
How could it be done? Pass in &A::_x, and later refer it using (*a_ptr).*m_ptr?
I thought, &A::_x will always refer to the same address, but different objects have different _x, how could it be done?
&A::_x is a pointer-to-member, which is not a pointer. Rather, think of it as some relative sort of construct which tells you where inside an object you find a particular member element. Only together with an instance reference can you locate the actual subobject of that instance which is given by the member pointer.
Compare:
struct Foo { int x; int y; };
Foo a = { 1, 2 };
Foo b = { 3, 4 };
Foo c = { 5, 6 };
int * p = &a.x; // ordinary pointer-to-int
int Foo::*pm = &Foo::x; // pointer-to-member
int result = a.*pm + b.*pm + c.*pm; // aggregate Foo::x
// point to a different member:
pm = &Foo::y;
result = a.*pm + b.*pm + c.*pm; // aggregate Foo::y
I have struct in class and not know how to call variables from struct, please help ;)
#include <iostream>
using namespace std;
class E
{
public:
struct X
{
int v;
};
};
int main(){
E object;
object.v=10; //not work
return 0;
}
I declared class B inside class A, how do I access it?
Just because you declare your struct B inside class A does not mean that an instance of class A automatically has the properties of struct B as members, nor does it mean that it automatically has an instance of struct B as a member.
There is no true relation between the two classes (A and B), besides scoping.
struct A {
struct B {
int v;
};
B inner_object;
};
int
main (int argc, char *argv[]) {
A object;
object.inner_object.v = 123;
}
It's not clear what you're actually trying to achieve, but here are two alternatives:
class E
{
public:
struct X
{
int v;
};
// 1. (a) Instantiate an 'X' within 'E':
X x;
};
int main()
{
// 1. (b) Modify the 'x' within an 'E':
E e;
e.x.v = 9;
// 2. Instantiate an 'X' outside 'E':
E::X x;
x.v = 10;
}
Your E class doesn't have a member of type struct X, you've just defined a nested struct X in there (i.e. you've defined a new type).
Try:
#include <iostream>
class E
{
public:
struct X { int v; };
X x; // an instance of `struct X`
};
int main(){
E object;
object.x.v = 1;
return 0;
}
You should define the struct out of the class like this:
#include <iostream>
using namespace std;
struct X
{
int v;
};
class E
{
public:
X var;
};
int main(){
E object;
object.var.v=10;
return 0;
}
If you give the struct no name it will work
class E
{
public:
struct
{
int v;
};
};
Otherwise write X x and write e.x.v
I'd like to add another use case for an internal struct/class and its usability. An inner struct is often used to declare a data only member of a class that packs together relevant information and as such we can enclose it all in a struct instead of loose data members lying around.
The inner struct/class is but a data only compartment, ie it has no functions (except maybe constructors).
#include <iostream>
class E
{
// E functions..
public:
struct X
{
int v;
// X variables..
} x;
// E variables..
};
int main()
{
E e;
e.x.v = 9;
std::cout << e.x.v << '\n';
E e2{5};
std::cout << e2.x.v << '\n';
// You can instantiate an X outside E like so:
//E::X xOut{24};
//std::cout << xOut.v << '\n';
// But you shouldn't want to in this scenario.
// X is only a data member (containing other data members)
// for use only inside the internal operations of E
// just like the other E's data members
}
This practice is widely used in graphics, where the inner struct will be sent as a Constant Buffer to HLSL.
But I find it neat and useful in many cases.