Considering that piece of code:
struct myStruct
{
myStruct *next;
};
Next is a pointer of struct declared in the struct definition, right?
What's the utility of - next - ? How can I use it?
Seems like it's an implementation of a linked-list.
You can use next if you want to chain such structures together to traverse them later. Of course, having other members in myStruct would make more sense.
example:
struct myStruct
{
int data;
myStruct *next;
};
myStruct st_1;
myStruct st_2;
st_1.data = 1;
st_2.data = 2;
st_1.next = &st_2; //st_1.next->data is now 2
The utility of this pointer is whatever you implement in myStruct. You can hold a direct relationship to other myStruct structs (through the pointer) using this pointer and directly manipulate them (i.e. like "knowing" about other objects).
For instance (note that for all intents and purposes, struct's in C++ are public classes),
class Test
{
public:
doSomethingToTheOtherStruct() {
if(t != NULL)
t->touch();
setTouched(bool touch) {
touched = touch;
}
setT(Test* other) {
t = other;
}
bool isTouched() const {
return touched;
}
private:
Test* t;
bool touched;
};
This class has some very simple methods which can demonstrate the power of using pointers. Now an example using it is below.
#include <iostream>
using namespace std;
int main()
{
Test t1;
Test t2;
Test* t3 = new Test;
// Notice that we set the pointers of each struct to point to a different one
// This is not necessary, but is definitely more useful than setting it to itself
// since you already have the "this" pointer in a class.
t1->setT(&t2);
t2->setT(t3);
t3->setT(&t1);
cout<< t1.isTouched() << t2.isTouched() << t3->isTouched() << endl;
t1->doSomethingToTheOtherStruct();
t2.doSomethingToTheOtherStruct();
cout<< t1.isTouched() << t2.isTouched() << t3->isTouched() << endl;
delete t3;
return 0;
}
Take note in the results of this code. t1 is never set to touched, but inadvertently (through the pointers), t2 and t3 become "touched."
The fact it is a pointer to the same class and that the member variable is called "next" suggests it is a linked list, as others have pointed out.
If the variable was a pointer to the same class but called "parent" it would most likely be some kind of parent/child relationship. (For example GUI widgets that have a parent that is also a widget).
What you might question is why you are allowed to do this: the answer is that pointers to data -types are all the same size, so the compiler will already know how many bytes it needs for this pointer.
For the same reason, you can have in your class (or struct) a pointer to a type for which the data type has only been declared and not defined. (Quite common to do).
That is correct. This kind of nested structs are used in linked lists.
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();
}
Background
I'd like facades to be applied on ad-hoc basis, and not baking them into the class itself. But I need to operate on the data, so I need this to be accessible from the facade. Here is a small example:
#include <array>
#include <iostream>
template <typename T>
struct x_getter
{
friend T;
double x() const
{
return (*real_self)[0];
}
void x(double new_x)
{
(*real_self)[0] = new_x;
}
private:
T* real_self = reinterpret_cast<T*>(this);
x_getter() = default; //prevents accidental creation
};
struct coordinates : std::array<double, 3>, x_getter<coordinates>
{
using std::array<double, 3>::array;
};
int main()
{
coordinates origin{};
std::cout << origin.x();
origin.x(12.7);
std::cout << ' ' << origin.x() << '\n';
}
It segfaults. Using something similar a while back, I got unlucky to be able to get away with it.
Question
How do I make this with type of target class be available in facade class?
My understanding of class layout
Somewhere inside of the object, in unordered manner, there are array and x_getter. By reinterpret_casting it, I'm trying to trick it to think that this is coordinates, but when it performs operator[], the offset which is used is a bit off, which goes outside of the object, thus segfaulting.
The problem here is that reinterpret_cast does not work because this pointer does not point at the beginning of coordinates class since it inherits from array before inheriting from x_getter. The memory layout for this class looks like this:
coordinates
|- std::array<double, 3>
|- x_getter
When you use reinterpret_cast<T*>(this) the address stored in this pointer is the address of x_getter object, but you force compiler to assume that it is actually an address of coordinates object. So dereferencing such a pointer to derived class leads to all kinds of undefined behavior.
Typically CRTP should use static_cast inside of method:
double x() const
{
return (*static_cast<TDerived const *>(this))[0];
}
Unlike reinterpret_cast, static_cast will properly adjust this pointer to correctly point at derived object.
I've got the classes:
struct A { // has no pointer members, POD - it's fine
int a, b;
char c;
};
struct B { // has no pointer members, but not POD - it's still fine
int a, b;
std::string s;
};
struct C { // has pointer members, it's not fine
int a,b;
char* cs;
};
I need to detect in compile time if any class has the properties of struct C, i.e. has pointers as members.
Short reasoning: I need to assure a user-defined type can be safely serialized and deserialized to some buffer by copying or assignment (e.g. struct A) or by providing user-defined serialize() and deserialize() methods in the class (e.g. struct B and struct c).
If B or C do not have these methods implemented, then compilation should fail, but if A does not have the methods, then the compilation should succeed.
Update:
The solution from Check if a class has a pointer data member works only for:
struct D {
int* p; // the pointer must be named 'p'
};
This issue is a different case. Can we reopen, please?
As of C++17, this is simply not possible.
You can test for a number of traits, but there is no trait that checks data members the way you need. std::is_pod<> (which will be deprecated in C++20) is the best you can get.
You can try magic_get.
It's a C++14 TMP solution for POD refrection, and it surely has its limitations (e.g. doesn't properly support references, bit fields, etc.), but you can enumerate PODs just the way you want (statically or dynamically), and then apply the std::is_pointer trait to check each field.
Example:
#include <iostream>
#include "boost/pfr/precise.hpp"
struct C {
int a, b;
char* cs;
};
int main() {
C var;
boost::pfr::for_each_field(var, [](const auto& field, std::size_t idx) {
std::cout << "field " << idx << ": is_pointer=" << std::is_pointer<std::remove_reference_t<decltype(field)>>() << '\n';
});
}
Output:
field 0: is_pointer=0
field 1: is_pointer=0
field 2: is_pointer=1
This is an XY problem.
The user that created the class needs to provide the serialize / deserialize functions according to the interface you provide. He knows if the class should be serializabile and if so how it should be done. It's the user responsibility, not yours. All you can do on your part is to provide an easy to use interface and tools to make it easier for the user to make a class serializabile.
Checking if a type has a pointer data member doesn't solve any issue and doesn't help in the slightest. You don't know if the pointer points to something the object owns exclusively, to something shared across objects, or points to a resource not-owned.
the question is how to get pointer to self inside method of a class without touching this:
class Foo
{
int a, b, c;
void Print();
};
This way in common compiler I can do this refering to first data field:
void Foo::Print()
{
cout << &a; // == this
}
But are there any ways to do this without data members when only function exists?
class Foo2
{
void Print();
};
p.s. don't even ask me why do I need this :)
For a POD class with at least one data member, the address of the class-type object is the same as the address of its first data member. This is because there can be no unnamed padding bytes before the first data member of a POD struct type. [In C++11, the rules are a bit different; I believe that this is true for all standard layout class types. I am not entirely familiar with the rules, however.]
For any other class type, there is no way to do this.
class Foo2
{
void Print();
};
#define OBJADDR(x) (th##x##s)
void Foo2::Print()
{
int i; // red herring, but the name MUST be `i`
std::cout << OBJADDR(i);
i; // to get rid of compiler warning about unused local variable
};
If your class has no data members then technically, instances of the class don't even exist. For convenience only, they are required to have size of at least 1 byte and have unique this pointers. If you inherit from a class with no data members, its size collapses to 0 and it disappears.
So no, there isn't any way to get the this pointer without using the this pointer. A less pragmatic version of C++ wouldn't even have this pointers for these objects, as they would have size 0.
You can probably hack it using the offsetof macro
void Foo::Print()
{
cout << static_cast<char *>(&a) - offsetof(Foo, a);
}
if you can't safely assume &a is the start.
So ... why do you need to do this?
Say you have:
struct c_struct {
int value;
/* other stuff */
void (* dump)();
};
and you'd like to, at some point:
c_struct_obj->dump();
I assume there's no way you could instantiate a c_struct object such that its particular "dump" function knows its particular "value" the way C++ methods know member variables (via the implicit "this" I suppose)? I guess I know the answer already ("no"). If so, are there other ways of using C structs in an OOPy way?
Sure, you just have to pass this by yourself:
struct c_struct {
int value;
/* other stuff */
void (* dump)(struct c_struct *this);
};
And then call it with:
c_struct_obj->dump(c_struct_obj);
You can use structs in this way but its a pain. All c++ member function get a *this pointer passed to them you can do the same but your dump functions will need to take the structure that its contained in as a parameter.
If you are using a C++ compiler, the only difference between a struct and a class is the default visibility of member variables (classes being private, structs being public). The this pointer is available within member functions.
struct test
{
int x;
void inc();
};
void test::inc()
{
x++;
}
int main(void)
{
test a;
a.x = 1;
a.inc();
int b = a.x;
return 0;
}
b == 2 here.
You can do this and can even do inheritance. But the interfacing with it is a total mess and you get nowhere near, for example, the resource safety involved with C++'s deterministic automatic cleanup. Ultimately, you CAN do OOP in C, but it's just not worth the hassle compared to just using C++, as well as all the other features that C++ offers.