I'd like to get some opinion from more experienced programmers. I have a structure like:
struct Position {
int x;
int y;
};
but I need to store for example longitude in a structure like:
struct Longitude {
int from;
int to;
};
both of them are actually the same with different names, but x and y are misleading in the case of Longitude. Would you use some typedef Position Longitude instead of defining Longitude structure (but then we have x/y there...)? Or create the same redundant structure with another names? Or maybe there are other alternatives?
I'd be inclined to keep them separate.
In C++ a struct and a class are identical constructs (excepting the default access of member variables and functions).
As your application evolves, you'll probably want to add more functions and member data to the structs. At that point the two definitions will start to diverge. Keeping them separate from the outset will assist this development.
If you're concerned about code duplication then you can always inherit from a base class or struct.
I think, if it is feasible, I would store it internally as either x/y or from/to and provide a public accessible interface for conversion.
How about this?
struct Position {
int x;
int y;
};
using Longitude = Position;
c++11 provides such sugar sintax, you have the same data with other name (you still have the same x/y stuff, but I dont really see the trouble of using them.)
I would make Position class parent of Longitude and user getters and setters instead bare attributes:
class Position {
public:
int getX() { return x; }
int getY() { return x; }
void setX(int x) { this->x = x; }
void setY(int y) { this->y = y; }
protected:
int x;
int y;
};
class Longitude : public Position {
public:
int getFrom() { return getX(); }
int getTo() { return getY(); }
void setFrom(int from) { setX(from); }
void setTo(int y) { setY(to); }
}
Related
I am stuck in a situation please help me out of this.
Thought:
To have a common Interface among different Detection algorithms(Say Circle, Triangle and Rectangle).
class IDetectionInterface()
{
public:
virtual void PerformDetection(Image & InputImage, DetectionStruct & DetectionData, DetectionParam & DetParam) = 0;
virtual ~IDetectionInterface()
{
}
};
where Image and DetectionStruct is a structure as below:
struct Image
{
unsigned char * pImageData;
int Width;
int Height;
};
struct DetectionStruct
{
Rect BoundingBox;
DectionType DetType;
};
struct Rect
{
int x;
int y;
int width;
int height;
};
enum DectionType
{
Circle = 0,
Triangle = 1,
Rectangle = 2
}
The Problem for me is that of DetectionParam, as Parameters of Detection Algorithms differ. Say for example
struct RectDetectionParam
{
int param1;
float param2;
double param3;
};
struct TriDetectionParam
{
float param1;
float param2;
double param3;
int param4;
};
struct CirDetectionParam
{
int param1;
float param2;
bool param3;
int param4;
float param5;
};
How can i get this to common interface as above.
Note: I don't want to put all the parameters in one structure which is a easiest solution, But it has its drawback if i change the algorithm then its respective parameters changes and we need to re write the structure again.
And Ofcource Yes, I will have the implementation of the interface(Abstract class)
Thanks in advance
Based on your example you could create a discriminated union to make the parameter sets generic:
struct DetectionParams {
DectionType detectionType; // Discriminator
union {
RectDetectionParam rectDect;
TriDetectionParam triDect;
CirDetectionParam cirDect;
};
};
Which of the union parts is used in the implementation is determined by the discriminator.
Another way is to use something like a parameter set based on unique parameter names (key strings):
struct DetectionParams {
std::map<std::string,std::any> params; // Note that std::any is available
// at the not yet official c++17 standard
};
is there a way how to simulate union behavior? See following code:
// this is ideal interface, which I would like to simulate
struct IdealInterface{
union{
struct{float r,g,b;};
struct{float x,y,z;};
};
};
// this is real parent object I should not change
struct Parent{
float r, g, b;
};
// this interface has ok behavior,
// but sizeof(Child0) != sizeof(Parent)
// which causes problems
struct Child0:public Parent{
float & x, & y, & z;
Child0() : Parent(), x(r), y(g), z(b){ };
};
// this has ok size, but interface is different
struct Child1:public Parent{
float & x(){ return r; }
float & y(){ return g; }
float & z(){ return b; }
};
So as described, I should keep Parent class, and I should derive my child class from Parent. I should not create different types and play with the type conversions. Thus, is it possible to create derived class (form Parent) with the same interface as IdealInterface class has?
If you mean identical behavior to a union then no, not without actually using a union.
You could always just hide the underlying data:
class Vertex
{
Vertex();
Vertex(float,float,float);
float& x() { return r;}
float& y() { return g;}
float& z() { return b;}
float& r() { return r;}
float& g() { return g;}
float& b() { return b;}
void r(float rComponent) { this->r = rComponent; }
...
private:
float r, g, b;
}
However, the downside to this approach is you must call the methods vs. accessing the underlying variable like you can do with the union.
If you want:
Vertex v;
v.x = 1.0f
Then you would want to use a union.
Answer:
Firstly, I have some words for commentators. I asked a pretty straight question. What I got? For example answers about sizeof properties, which were not posed (btw, yeah in this case I have guarantee about sizeof - this is c++, not a kind of today common wild language).
Why I cannot use IdealInterface. Problem is more complex. I want to edit bigger pack of code with introduced constraints and dependencies. Thus this is the question and I cannot redefine question, however it implies simpler solution.
Answer: NO, it is not possible.
Why? It is based on properties of anonymous structs and unions.
Nearest approach: For my purpose, nearest approach is to use memory model as parameter.
struct BASIC_MEMORY_MODEL{
float x, y, z;
BASIC_MEMORY_MODEL() :x(), y(), z(){}
};
struct ADVANCED_MEMORY_MODEL{
union{
struct { float x, y, z; };
struct { float r, g, b; };
};
ADVANCED_MEMORY_MODEL() :x(), y(), z(){}
};
template<typename MEMORY_MODEL = BASIC_MEMORY_MODEL>
struct ParentBase : public MEMORY_MODEL{};
typedef ParentBase<> Parent;
struct Child : public ParentBase < ADVANCED_MEMORY_MODEL > {};
I have a struct that represents a vertex. It has x, y and z fields as well as several others. Recently I came into conclusion that for certain functionality I will need to access the coordinates of the vertex as an array. I didn't want to "pollute" the code with temporary variables or change all places that look like this v.y to this v.coord[1] which is not nice nor elegant. So I thought about using a union. Something like this should work:
struct {
float x,y,z;
} Point;
struct {
union {
float coord[3];
Point p;
};
} Vertex;
This is good, but not perfect. The point class has no point being there. I want to be able to access y coordinate simply by typing v.y (and not v.p.y).
Can you suggest a hack to solve this (or tell me that it is not possible)?
A good C++ approach is to use named accessors that return references to the elements:
class Point {
public:
float& operator[](int x) { assert(x <= 2); return coords_[x]; }
float operator[](int x) const { assert(x <= 2); return coords_[x]; }
float& X() { return coords_[0]; }
float X() const { return coords_[0]; }
float& Y() { return coords_[1]; }
float Y() const { return coords_[1]; }
float& Z() { return coords_[2]; }
float Z() const { return coords_[2]; }
private:
float coords_[3];
};
With this approach, given a Point p;, you can use both p[0] and p.X() to access the initial element of the internal coords_ array.
OK, this should work for you
struct {
union {
float coord[3];
struct
{
float x,y,z;
};
};
} Vertex;
What this code does is that it unions the array with the structure, so they share the same memory. Since the structure doesn't contain a name, it is accessible without a name, just like the union itself.
Can I have a method which takes arguments that are denoted with the same names as the members of the holding class? I tried to use this:
class Foo {
public:
int x, y;
void set_values(int x, int y)
{
x = x;
y = y;
};
};
... but it doesn't seem to work.
Is there any way of accessing the the instance the namespace of which I'm working in, similar to JavaScript's this or Python's self?
It's generally a good idea to avoid this kind of confusion by using a naming convention for member variables. For example, camelCaseWithUnderScore_ is quite common. That way you would end up with x_ = x;, which is still a bit funny to read out loud, but is fairly unambiguous on the screen.
If you absolutely need to have the variables and arguments called the same, then you can use the this pointer to be specific:
class Foo {
public:
int x, y;
void set_values(int x, int y)
{
this->x = x;
this->y = y;
}
};
By the way, note the trailing semi-colon on the class definition -- that is needed to compile successfully.
Yes, you should be able to write this using the "this" keyword (which is a pointer in C++):
class Foo {
public:
int x, y;
void set_values(int x, int y)
{
this->x = x;
this->y = y;
}
}
In C++ the current instance is referenced by the const pointer this.
class Foo {
public:
int x, y;
void set_values(int x, int y)
{
this->x = x;
this->y = y;
};
};
There's no way to do something like this, in C++ is there?
union {
{
Scalar x, y;
}
Scalar v[2];
};
Where x == v[0] and y == v[1]?
Since you are using C++ and not C, and since they are of the same types, why not just make x a reference to v[0] and y a reference to v[1]
How about
union {
struct {
int x;
int y;
};
int v[2];
};
edit:
union a {
struct b { int first, second; } bee;
int v[2];
};
Ugly, but that's more accurate
Try this:
template<class T>
struct U1
{
U1();
T v[2];
T& x;
T& y;
};
template<class T>
U1<T>::U1()
:x(v[0])
,y(v[1])
{}
int main()
{
U1<int> data;
data.x = 1;
data.y = 2;
}
I've used something like this before. I'm not sure its 100% OK by the standard, but it seems to be OK with any compilers I've needed to use it on.
struct Vec2
{
float x;
float y;
float& operator[](int i) { return *(&x+i); }
};
You can add bounds checking etc to operator[] if you want ( you probably should want) and you can provide a const version of operator[] too.
If you're concerned about padding (and don't want to add the appropriate platform specific bits to force the struct to be unpadded) then you can use:
struct Vec2
{
float x;
float y;
float& operator[](int i) {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
const float& operator[](int i) const {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
};
I was looking for a similair thing and eventually came up with a solution.
I was looking to have a data storage object that I could use as both an array of values and as individual values (for end-user flexibility in writing Arduino libraries).
Here is what I came up with:
class data{
float _array[3];
public:
float& X = _array[0];
float& Y = _array[1];
float& Z = _array[2];
float& operator[](int index){
if (index >= 3) return _array[0]; //Make this action whatever you want...
return _array[index];
}
float* operator&(){return _array;}
};
int main(){
data Test_Vector;
Test_Vector[0] = 1.23; Test_Vector[1] = 2.34; Test_Vector[2] = 3.45;
cout<<"Member X = "<<Test_Vector.X;
cout<<"Member Y = "<<Test_Vector.Y;
cout<<"Member Z = "<<Test_Vector.Z;
float* vector_array = &Test_Vector;
cout<<"Array = {"<<vector_array[0]<<", "<<vector_array[1]<<", "<<vector_array[2]<<"}";
}
Thanks to Operator overloading, we can use the data object as if was an array and we can use it for pass-by-reference in function calls (just like an array)!
If someone with More C++ experience has a better way of applying this end product, I would love to see it!
EDIT: Changed up the code to be more cross-platform friendly
Given your example:
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
As others have noted, in general, the standard does not guarantee that there will be no padding between x and y, and actually compilers inserting padding in structures is pretty common behavior.
On the other hand, with solutions like:
struct U
{
int v[2];
int& x;
int& y;
};
U::U()
: x(v[0])
, y(v[1])
{}
what I don't like mainly is the fact that I have to mention x, y twice. For cases where I have more than just a few elements (say 10), this becomes much less readable and harder to maintain - e.g. if you want to change the order of x,y then you have to change the indexes below too (well not mandatory but otherwise order in memory wouldn't match order of fields, which would not be recommended). Also, U can no longer be a POD since it needs a user-defined constructor. And finally, the x & y references consume additional memory.
Hence, the (acceptable for me) compromise I've come up with is:
struct Point
{
enum CoordType
{
X,
Y,
COUNT
};
int coords[CoordType::COUNT];
};
typedef Point::CoordType PtCoord;
With this you can then do:
Point p;
for ( int i = 0; i < PtCoord::COUNT; i++ )
p.coords[i] = 100;
std::cout << p.coords[PtCoord::X] << " " << p.coords[PtCoord::Y] << std::endl;
// 100 100
A bit sophisticated but I prefer this over the references suggestion.
Depending on what "Scalar" is, yes, you can do that in C++. The syntax is almost exactly (maybe even exactly exactly, but I'm rusty on unions) what you wrote in your example. It's the same as C, except there are restrictions on the types that can be in the unions (IIRC they must have a default constructor). Here's the relevant Wikipedia article.
With C++11 you have anonymous unions and structs which just export their definitions to the enclosing scope, so you can do this:
typedef int Scalar;
struct Vector
{
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
};