Difference between the dot operator and a get method - c++

I have a vector class
class Vector {
public:
double x, y, z;
Vector add(Vector v) {
return Vector(x+v.x, y+v.y, z+v.z);
}
};
and I have a class Ray
class Ray {
public:
Vector origin, direction;
Vector getOrigin() { return origin; }
};
In some method, I do:
Vector x = ray.origin().add(normal); // doesn't work
Vector y = ray.getRayOrigin().add(normal); // works
error message: Type vector doesn't provide a call operator
Why can't I just access the vector directly?

Because origin is not a function. Remove the parentheses when you access it.

Xīcò has the correct solution, but not the right symptom.
origin doesn't have to be a function. The Vector class could overload operator() and be called as if it were a function, and that's the message the compiler is trying to get across.
ray.origin allows anyone to do anything to ray's origin member including things that could be harmful to ray. Very uncool. The purpose of setters and getters is to regulate access to member variables. The goal is self defence.
OP's getOrigin method doesn't return origin. It returns a copy of origin. A malicious cretin can do anything they want to the copy without breaking ray. This is most often the right way unless the object returned is intended to be modified or prohibitively expensive to copy. In that modification case, lock down the returned object with private data, and getters and setters of it's own. In the expensive copy case, declare the return value to be const to reduce the possibility of damage.
A good setter will vet all input to the origin member before allowing the change to take place. If the caller tries to feed in values that are inconsistent with origin, ray can slap it down.
Directly accessing origin through . allows ray no defence whatsoever. It also prevents ray from changing the implementation of origin without also chancing origin's users.
Whether these are concerns with a pair of simple classes like Vector and Ray, is a matter of coding style and necessity, but locking down data access to the minimum necessary is generally a good habit to get into and a must when developing complicated software.

class Vector {
public:
double x, y, z;
Vector add(Vector v) {
return Vector(x+v.x, y+v.y, z+v.z);
}
};
class Ray {
public:
Vector origin, direction;
Vector getOrigin() { return origin; }
Vector& getOrigin2() { return origin; }
};
int main() {
Ray ray;
Vector v1 = ray.origin; // returns origin member
Vector v2 = ray.getOrigin(); // returns a copy of origin member
Vector v3 = ray.getOrigin2(); // same as v1, returns origin member
}

Related

Assign a point to the class member

i trying to implement the following link http://in.mathworks.com/help/vision/examples/motion-based-multiple-object-tracking.html in opencv and c++.
I have created a class say ex:
class assign
{
vector <int> id;
vector <int> area;
vector<Point> centroid;
};
After this i have created an object
assign id;
Now i want to assign the centroid value and other values too. what i tried is
id.centroid (p);
where p is a "point" But i'm getting error for this. I don't know where i'm going wrong.
centroid is a private member of class assign. If you want to access it directly, you should make it public
class assign
{
public:
vector<Point> centroid;
//...
};
And if you want to add a Point into centroid, you should
id.centroid.push_back(p);
The main answer is already given by songyuanyao. What I want to add is a possible solution which allows you to use the member variables like you already tried it.
If you want to get and set the member centroid with id.centroid(p) you could go with the following class declaration:
class Assign
{
public:
vector<Point> centroid();
void centroid(vector<Point> c);
private:
vector<Point> m_centroid;
};
The definition might then look like this:
// getter
vector<Point> Assign::centroid() {
return m_centroid;
}
// setter
void Assign::centroid(vector<Point> c) {
m_centroid = c;
}
Now if you use id.centroid(p) to set the member the overloaded setter will be called and will set the variable. If you call p = id.centroid() (empty parameter list) the overloaded getter will be called and will return the current m_centroid.
To add to the previous answers; if you want to expand on your class this can be done for you during construction of your object.
class Assign {
private:
std::vector<int> m_vIds;
std::vector<int> m_vAreas;
std::vector<Vec2> m_vCentroids;
public:
Assign(); // Default Constructor Same As What You Have But Not Declared.
Assign( int* pIds, int* pAreas, int* pCentroids ); // Create By Using Pointers
// Create By Passing In Either Pre Filled Vectors Or Even An Empty
// Vectors To Be Filled Out Later. Passes By Reference. This Will
// Also Set The Variables That Are Passed In From The Caller.
Assign( std::vector<int>& vIds, std::vector<int>& vAreas, std::vector<Vec2>& vCentroids );
// Since You Are Using Vectors Within This Class It Is Also Good To
// Have A Destructor To Clear These Out Once The Object Is Done And
// Ready To Be Destroyed Or Removed From Memory
~Assign();
};
// The Destructor Would Look Like This
Assign::~Asign() {
if ( !m_vIds.empty() ) {
m_vIds.clear();
}
if ( !m_vAreas.empty() ) {
m_vAreas.clear();
}
if ( !m_vCentroids.empty() ) {
m_vCentroids.empty();
}
} // ~Assign
// NOTE: I used Vec2 instead of point due to my use of programming
// 2D & 3D Graphics Rendering Engines; Most Graphics APIs and Libraries
// along with Most Math Libraries Will Not Have A Point Class; Most Will
// Use Vec2 or Vec3 - Vector2 or Vector3 & Vector4 Since in terms of
// memory they are exactly the same thing. It is up to you to know which
// objects are points or locations, and which are vectors as in forces,
// velocities, accelerations, directions, normals etc. The only major
// difference between a discrete Point Class or Structure versus a Vector
// Class is that the Vector Class usually has operations defined with it
// to do vector mathematics such as addition, subtraction, multiplication by
// value, multiplication by vector, division by value, division by vector,
// cross & dot product, comparisons, testing if vector is 0, setting it to
// be a normal vector, returning the magnitude or length and a few others.
// The general point class or object is usually just data values or
// simply coordinates without operations.

c++ get/set method in class, Which data type I have to use?

I have a class like below
class Circle{
private:
int radius;
Circle* next
}
And I gonna creat set/get method...but i have no idea which data type i have to use.
int Circle::getRadius() const{return radius}
or
int& Circle::getRadius() const{return radius}
void Circle::setRadius(int r)
or
void Circle::setRadius(int& r)
CirCle* Circle::getNext() const{return next}
or
Circle& Circle::getNext() const{return *(next)}
void Circle::setNext(Circle& circle)
{
next = new Circle;
next = circle;
}
or
void Circle::setRadius(Circle circle)
{
next = new Circle;
next = circle;
}
or
void Circle::setRadius(Circle* circle)
{
next = circle;
}
I'm famliar with Java quite a lot. And Java argument are all reference. But cpp is quite different so it drive me crazy. Thanks for your help.
First I'd just recommend going through some C++ tutorials. Your question is probably going to get downvoted here because it looks like you really didn't try to search for a solution to your problem, but rather just ask SO for help.
Need to understand a few things with C++. Learn pass by reference vs pass by value. Are primitives passed by reference or by value?
You also should look at pointers. You're kinda mixing up syntax in there a little bit. * is to de reference a pointer. & is to get the memory address of a certain object.
Explore these concepts and you'll find the answer to your question, and learn more about C++.
Try looking at this site for some info.
http://www.learncpp.com/cpp-tutorial/84-access-functions-and-encapsulation/
If you have any other questions, feel free to let me know. :)
Happy to help.
You should use:
int Circle::getRadius() const{return radius}
Why?
First because you don't want your getter to modify your object (that is done by the const after () ), and you don't want caller to your getter to be able to modify your radius either, in fact:
int& Circle::getRadius() const{return radius}
should not even compile. it would have to be:
const int& Circle::getRadius() const{return radius}
In this case the reference to radius returned is const and therefore, the caller cannot modify the radius via this getter.
Although it's totally correct, when dealing with primitive types in C++ one usually prefer to copy rather than to hold const reference. Why? because copy on primitive costs less than have to dereference it each time you need to use it.
Use:
void Circle::setRadius(int r)
Why?
Like before, using an int, prefere to copy the value to use a reference that you'll have to (implicitly) derefence on use.
In this case:
CirCle* Circle::getNext() const{return next}
or
Circle& Circle::getNext() const{return *(next)}
Why? One thing is sure, you won't be able to use the second one, like in the first case your return value will have to be const Circle&. Plus, you want to be able to return a "invalid" value. In C++ not like in Java, you cannot return an "invalid" reference. So the best thing is to return a pointer which will have "NULL" value if "invalid".
After that, if you want your caller to be able to modify the "next Circle" you'll have to go with a Circle* return. If you don't want your caller to be able to modify the result you'll have to go with a const Circle*
const CirCle* Circle::getNext() const{return next}
or
Circle* Circle::getNext() const{return next}
Some people think it's a bad thing to have a const method that return a non const pointer. For certain reasons, I don't, but both are syntaxly correct.
Use:
void Circle::setNext(Circle* circle)
{
next = circle;
}
Why? For your SetNext, it depends on who will have to manage the memory (ie destruction) used by your "next circle" if it's an external class (I think it's the easiest), like a manager for exemple go with that
For your setRadius, simply use:
void Circle::setRadius(int value)
{
radius = value;
}
[Edit: ] Example of Circle class:
Here what would an external manager (like a Circle list) would look like:
class CircleList //Manager as I told
{
public:
Circle* createCircle(int _radius)
{
Circle* circle = new circle(_radius);
//manage here the add to the list of circle
}
void destroyCircle(Circle* _circle)
{
//Manage here the remove of the list
delete _circle;
}
~CircleList()
{
while( first )
{
destroyCircle(first);
}
}
private:
Circle* first = NULL;
};
class Circle
{
public:
Circle(int _radius) : radius(_radius) { }
void setNext(Circle* _circle)
{
next = _circle;
}
Circle* getNext() const
{
return next;
}
void setRadius(int _value)
{
radius = _value;
}
private:
Circle* next = NULL;
int radius = -1;
};
Here, only CircleList manage the list and memory used by circles. If you want to encapsulate even more, make setNext/getNext private and CircleList a friend of circle (once again some will judge, let them :p)
If you wanted to manage memory inside the Circle class, a circle would exist only if its predecessor exist, and if you delete one Circle you would delete all the ones after in the list(I can't see the application this...). In this case you would have something like:
class Circle
{
public:
Circle(int _radius) : radius(_radius) { }
void setNext(int _radius)
{
next = new Circle(radius);
}
void removeNext()
{
delete next;
next = NULL;
}
Circle* getNext() const
{
return next;
}
void setRadius(int _value)
{
radius = _value;
}
~Circle()
{
delete next;
}
private:
Circle* next = NULL;
int radius = -1;
};
Note that you now have a destructor on circle and that when destroying one circle, it destroys all the circle that follow in the list (only way I see to avoid leak and external "holder" of circles)
Plus if you have a really long list, it may cause problems when destroying as a destructor calls (implicitly) the destructor of its successor, you may end up with a stack overflow.
That's why I was telling you that a manager external to the class was the best solution to me, but maybe some other people have better ideas :)
First of all, in Java all are passed by value!
In case of references, it is passed the value of the reference. Because of that it is misunderstood generally.
In case of C++, you can return/pass by value or reference. In your example, int value would be returned by value simply; supposing that probably you would only need its value.
In case of a complex object, you could use reference or pointer. They are actually -almost- the same. You can find sources to look the differences in detail, but here let me tell simply: Pointers are kept in C++ to be compatible with C; references are considered instead. So, you could try to use references mostly.
You need to know the difference of using values by copy and by reference and using pointers.
Passing values by copy, say:
int radius = 2;
setRadius( radius );
Creates a copy of 2 within the function. Whatever changes you do to that value within the function won't change the variable radius that you created outside.
Pointers hold a value that is the memory address of some variable. No matter the type you're using, a pointer only takes up 4 bytes in memory.
int radius = 2;
int *radiusPtr = &radius; // radiusPtr now points to the address of radius
std::cout << *radiusPtr << std::endl; // > 2
setRadius( radiusPtr ); // Passing a pointer to setRadius
Passing by reference is, in a way, similar to pointers but it's defined as "passing the variable itself". You could use a pointer to change the value of the pointed left value, but you can use a reference to change the values of the original variable. You could even use a reference to a pointer to change the original pointer.
int radius = 2;
setRadius( radius ); // Passing by reference is done in the same way as by value, the difference is the method signature -> setRadius( int &radius );
int &radiusRef = radius;
radiusRef = 3;
std::cout << radius << std::endl; // > 3
To answer what to use. Depends on your types and what you need.
//If you use a setter with reference, like
void setRadius( int& radius );
//You cannot pass literal values like
setRadius( 2 );
setRadius( int(2) );
//Only variables/lvalues
int radius = 2;
setRadius( radius );
If you are using a more complex structure then the reference, or a pointer, makes more sense. It's also more efficient to use a reference than it is to copy a huge structure.
The same applies when returning values. If you don't want the user to change the value of your attribute, then a pointer or reference are not the best option. But you could always use a const pointer or reference,
const int *getRadius() const;
const int &getRadius() const;
To prevent the user from changing the radius from outside, yet be able to use the value. The last const means that this function can be called even if you're using a const Circle, or const *Circle or const &Circle.
I'd say for ints you could just use copies, but for more complex structures, like the Circle, consider using references or pointers. In your case, you even store pointers to the next Circle, so a pointer should do.
class Circle{
public:
void SetRadius(int const& value){ radius = value;} // 1
int GetRadius() const {return radius;} // 2
void SetCircle(std::shared_ptr<Circle> const& pCircle) { next = pCircle;} // 3
std::shared_ptr<Circle> GetCircle() { return next; } // 4
private:
int radius;
std::shared_ptr<Circle> next;
}
1 and 3 This is how you write set functions. Period.
2 and 4 Return by value and dont break the encapsulation
3 and 4 NEVER use raw pointers

VBO of std::vector<MyClass*> and correct strides

I'm wondering how to get the maximum data locality and performance for the following problem without data copy.
I've a std::vector< MyClass* > where MyClass is something like
class MyClass
{
public:
MyClass(int n,double px,double py,double pz)
{
someField=n;
x=px;
y=py;
z=pz;
anotherField=100;
anotherUnusefulField=-10.0;
}
int someField;
int anotherField;
double x;
double y;
double z;
double anotherUnusefulField;
};
std::vector<MyClass*> myClassVector;
// add some values and set x,y,z
for (std::vector<MyClass*>::iterator iter = myClassVector.begin(); iter!=myClassVector.end();++iter)
{
MyClass *tmp = *iter;
tmp->x+=1.0;
tmp->y+=2.0;
tmp->z+=3.0;
}
I'm iterating frequently on these data and I also would like to enforce data locality. The data contained in the pointer to MyClass should be sent to a OpenGL vertex array, where the vertices are ONLY determined by x,y,z variables. As you may imagine is difficult to correctly set the strides, so I'm here to ask if there are other (portable) solution to this problem.
(p.s. I've already read the post VBOs with std::vector but my case is basically different because I have pointers and I also have other variables inside the class.)
I have pointers
Those pointers are useless to OpenGL, as they're in client address space. Also OpenGL doesn't dereference second level pointers.
and I also have other variables inside the class.
Well, then don't do this. If you passed those class instances to OpenGL you'd copy a lot of useless data. I recommend you just store a index into a tightly packed std::vector or array in your class members, and a reference to the vector/array itself. You can use getter/setter/referencer member functions to abstract away the access to the vector, i.e.
class …
{
// …
std::vector<v_t> *v;
size_t index_v;
x_t getX() const { return (*v)[index_v]; }
x_t setX(x_t x) { return (*v)[index_v] = x;}
x_t &x() { return (*v)[index_v]; }
};

C++: direct accessors or access functions within class?

I have two versions of a class named 'vertex', one that uses direct accessors for the coordinates:
struct vertex
{
// Coordinates
std::array<double, 3> coords;
// Direct accessors
double & x;
double & y;
double & z;
// Constructor
template<typename... T> vertex(T &&... coordinates) :
coords{{ std::forward<T>(coordinates)... }},
x( coords[0] ), y( coords[1] ), z( coords[2] )
{ }
};
and other that uses access functions:
struct vertex
{
// Coordinates
std::array<double, 3> coords;
// Access functions
double & x() { return coords[0]; }
double & y() { return coords[1]; }
double & z() { return coords[2]; }
// Constructor
template<typename... T> vertex(T &&... coordinates) :
coords{{ std::forward<T>(coordinates)... }}
{ }
};
Which approach is better for this specific case? I would appreciate any other suggestions. Thanks!
I normally would go through functions, for encapsulation purposes.
But this is a quite particular case, because you are dealing with vertices. If you plan to manipulate a lot of those objects (rendering or trasforming meshes), then direct access has some benefits in term of performances.
Some graphic libraries use direct access (and some books suggests too) for vector-like operations in real-time environments where efficiency it's a must.
Have a look at Ogre::Vector3 for example.
Despite that I wouldn't do what you are doing in your first solution. Like other said
you are doubling the used space for no reason (for eventually a lot of vertices).
From my point of view, in a context of high performance this could be the best vertex:
class Vertex
{
public:
double X;
double Y;
double Z;
};
I think getters are better. First approach creates objects of bigger size for no real benefit.
I'd go with the function - it allows you to change your mind more easily in the future. Furthermore, you can't do this:
double & x() { return coords[0]; }
double & y() { return coords[1]; }
double & z() { return coords[2]; }
double x() const { return coords[0]; }
double y() const { return coords[1]; }
double z() const { return coords[2]; }
with the accessors.
Well, I'd say the first one is better for a few reasons:
You're unlikely to be performing additional processing mid-get or mid-set on a vertex coordinate.
Since operations on vertices are usually done very often in loops and vertices are often related to rendering, the first option (direct access) is likely to give you better performance.
Encapsulation isn't a must if you're going to be directly accessing members with trivial getters and setters. It's just Object Orientation by dogma.
That being said, the second approach has advantages too, such as an unchanging interface more resilient to change. I'd still stick with the first one.
If you really want direct write access to the members (which it appears you do and may be appropriate in this case), then I would suggest the inline functions. This gives you flexibility to profile and inject extra capability into the accesses in the future should you desire to do so.
I think the best solution would be to remove the reference of the second option and add setters. But if these are the only choices the second would be slightly better.

Are there some practical examples that use Object::*

I just heard of that there is a kind of type like this,a point to Object member. Here is it
class Point{float x, y;};
float Point::*p2 = &Point::x;
but I haven't use before,and wonder some-body really use it.Do you have any experience of that?
This is useful if you want to apply the same treatment to members without duplicating the code.
vector<Point> points; // suppose it has many elements
vector<double> Project(const vector<Point> points, int Point::* coord)
{
vector<double> result;
for (auto& p: points)
result.push_back(p.*coord);
return result;
}
// usage:
vector<double> Xs = Project(points, &Point::x);
vector<double> Ys = Project(points, &Point::y);
There are many other usages as well, for instance fast delegates (link).
Those are pointers to class members and are used for example to implement various functor classes (e.g.: boost::function or std::function).
http://en.cppreference.com/w/cpp/utility/functional/mem_fn
or
http://www.cplusplus.com/reference/std/functional/mem_fun/
class Point {
public: //public variables (can be accessed by outsider)
float x, y;
private: //private variables if you have any
};
Now to create an object you would do Point p, and you can access the elements by doing p.x and p.y, just like you would with a struct object.
If you want to create a class pointer, do Point *p, now if you want to access x, y, then you would do p->a and p->b. If you have another object Point t, and you want assign address of t to p, then you can do p = &t.