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;
};
};
Related
Let's say I have this simple class with a const int member variable:
class MyClass{
public:
Myclass(int x, int y);
private:
const int importantNumber;
int anotherNumber;
};
MyClass::MyClass(int x, int y) :importantNumber{x}
{
this->anotherNumber = y;
}
Since int importantNumber is const, I can only set it during the creation of the object by the constructor (with a member initialization list, as seen above).
Now, the question: how could I possibly add validation for argument x given to the constructor before actually creating importantNumber with that value? Is it possible to create a static int MyClass::validation(int a) and use it on the member initialization list of the constructor like importantNumber{validation(x)}?
Even if it's possible, is there a better way to do it?
You just add it.
MyClass::MyClass(int x, int y) : importantNumber{validate(x)}
{
this->anotherNumber = y;
}
The int validate(int original) function can now return something other than x or throw an exception or assert or ask the user for confirmation, whichever you deem appropriate.
If it is just a simple check and you don't want to write a validate function you can use a lambda:
MyClass::MyClass(int x, int y) :importantNumber{
[](int number){
assert(number > 0);
return number;
}(x)}
{
this->anotherNumber = y;
}
Although this can get a bit convoluted if you overdo it.
You can use the ternary operator condition ? true : false in the constructor if you want to validate with a simple condition:
class MyClass{
public:
MyClass(int x, int y);
private:
const int importantNumber;
int anotherNumber;
};
MyClass::MyClass(int x, int y) : importantNumber(x > 0 ? x : 0)
{
this->anotherNumber = y;
}
However, be warned that things can quickly become difficult to read if you overdo it with this operator.
For something more complex, you could do something like this:
int validateIntegral(int x) const
{
// Do validation on 'x'...
return x;
}
class MyClass{
public:
MyClass(int x, int y);
private:
const int importantNumber;
int anotherNumber;
};
MyClass::MyClass(int x, int y) : importantNumber(validateIntegral(x))
{
this->anotherNumber = y;
}
Use factory function for creating a class instead of constructor.
class MyClass
{
public:
static MyClass* create (int x, int y);
private:
MyClass(int x, int y);
private:
const int importantNumber;
int anotherNumber;
};
MyClass* MyClass::create (int x, int y)
{
return x > 0 ? new MyClass(x, y) : NULL;
}
When you need some advanced validation of parameters, factories have following advantages:
They avoid creation of object in memory if tests fail
They have more flexibility over checking parameters in initialization
list
You can return NULL if you dont need exceptions nor you want to have some ".is_valid()" member function for your class.
Is there an equivalent to Delphi's absolute in C++? I want to do the following:
// Structure A
struct A
{
double X;
double Y;
double Z;
}
// Structure B
struct B : A
{
double U absolute X;
double V absolute Y;
double W absolute Z;
}
I can use double & U = X in structure B but this will generate an additional pointer and change the size of the structure. Union is - I think - also not a solution, because structure B inherits structure A.
What I really want is to have access to the same memory by accessing for example X or U.
I like the idea of user2079303's answers, but want to inverse it.
Note - the question is named wrong and is violating "what is your real goal" or "show me your Z" rule. We do not need to mimic absolute keyword - it is total nonsense! we want to make pseudonyms for the record properties and use them interchangeably.
What I really want is to have access to the same memory by accessing for example X or U.
The quoted line is the ONLY line in the question that talks about the problem essence - making full pseudonyms.
So, let's start where user2079303 stopped and use the fact that C's unions do not have to be named, like it was used in https://stackoverflow.com/a/13624921/976391
So we just inverse the scopes.
/*union*/ struct coordinates {
/*struct*/ union {
double X;
double U;
};
/*struct*/ union {
double Y;
double V;
};
/*struct*/ union {
double Z;
double W;
};
};
Short version: There is no equivalent of the described language feature.
Long version C++:
There isn't an equivalent in C++. The member reference that you suggest gives you the same syntax, but indeed increases the size of the object.
Another close alternative is a member function, that returns a reference. That has no overhead (assuming inline expansion). A function call has different syntax than referencing a member though. But perhaps having identical syntax with member access is not important so this is what I suggest.
Long version C:
There is no inheritance in C at all, so there is nothing like the described "absolute" in it either.
we have several kinds of coordinates. Some of them are named x, y, z others (in another system) are named u, v, w.
Given this context, I would suggest a union (EDIT: It's better to swap the union and struct relation, see https://stackoverflow.com/a/41148089/2079303):
union coordinates {
struct {
float x, y, z;
} xyz;
struct {
float u, v, w;
} uvw;
};
If you want to interchangeably use XYZ and UVW, you can let each convert to the other.
// forward declare
struct B;
struct A
{
double X;
double Y;
double Z;
operator B() const;
}
struct B
{
double U;
double V;
double W;
operator A() const;
}
A::operator B() const { B b; b.U = X; b.V = Y; b.W = Z; return b; }
B::operator A() const { A a; a.X = U; a.Y = V; a.Z = W; return a; }
I have two different structs which I want to convert to each other like this:
PointI a = PointI(3,5);
PointF b = a;
I assume that I will need to do something like the code below:
struct PointF
{
PointF operator=(PointI point){
x = point.x;
y = point.y;
return *this;
}
float x, y;
};
struct PointI
{
PointI operator=(PointF point)
{
x = point.x;
y = point.y;
return *this;
}
int x, y;
};
But the problem is that PointF uses PointI before it is declared. From what I've read in other questions, I understand that I can declare PointI before defining both structs, and then use a pointer. Though it seems that I won't be able to access the variables x and y from that pointer, as these are not defined yet.
Is there a way I can add these variables to the struct declaration before defining them? Or is there a better way to solve this problem?
First, forward declare one of the structs and fully declare the other. You'll need to use either a reference or pointer for the forward declared type, since the compiler doesn't have its definition yet:
struct PointI;
struct PointF
{
PointF operator=(const PointI& point);
float x, y;
};
Next, you need to fully declare the struct you forward declared:
struct PointI
{
PointI operator=(const PointF& point);
int x, y;
};
Now you can go ahead and define the operator= functions for each:
PointF PointF::operator=(const PointI& point)
{
x = point.x;
y = point.y;
return *this;
}
PointI PointI::operator=(const PointF& point)
{
x = point.x;
y = point.y;
return *this;
}
Note that you should change your operator= functions to return references rather than copies, but that's outside the scope of this question/answer.
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); }
}
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];
};
};