C++ Accessing operator function in inherited class - c++

I am currently writing an application where I use the Eigen-Library for complex 3D-Math. Because I needed distinct point and vector classes, my point3d-class looks like this:
class point3d : public Eigen::Vector4d
{
public:
point3d(){}
point3d(double x, double y, double z) : Eigen::Vector4d(x, y, z, 1) {}
void fromString(std::string input);
};
Now I want to create a member function of this class that allows me to parse lines of OBJ-files which look like this:
v 2.8 0.52 10.18
as such point. This is how I intend to design my parsing function
void point3d::fromString(std::string input)
{
char* buf = strdup(input.c_str());
if (strtok(buf, " ") == "v")
{
;
strtok(buf, " ");
this-x = std::stod(strtok(buf, " "));
this->y = std::stod(strtok(buf, " "));
this->z = std::stod(strtok(buf, " "));
}
}
My problem is that Eigen does not allow me to access the data stored in Vector4d as this->x, this-y, this->z and so on. Instead, you'd usually access it as Vector4d v; v[0], v[1], v[2] etc. I think the way it does that is by using a
double Eigen::Vector4d::operator[](unsigned int index){...}
function.
I don't know how exactly one would access that data in a derived class. What do I have to do to access this data within that function so that I can write to the x, y, z values?

You can do
(*this)[0]
and so on in order to call the base class operator[].

x, y, z aren't member variables of Eigen::Vector4d, but methods. You can access them from your derived class using this->x() etc (or Vector4d::x()). What also works is (*this)[0] or (*this)(0). If you need to access x(), y(), z() frequently in your class, you could write once:
using Vector4d::x;
using Vector4d::y;
using Vector4d::z;
And afterwards access them using just x(), y(), z(). However, this may cause some shadowing conflicts (if you name local variables the same way).

Related

Why is it not possible to use the dot operator (.) with `this` in C++? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
I would like to know why the use of this.var to access internal class variables does not work in my case. I have to resort to Class::var or make use of another way of changing my variables.
In my case this does work:
Vec3D::Vec3D(float x, float y, float z){
Vec3D::x = x;
Vec3D::y = y;
Vec3D::z = z;
Vec3D::label = "";
}
And so does this:
Vec3D::Vec3D(float x, float y, float z):
x(x),y(y),z(z){}
However, if I try this:
Vec3D::Vec3D(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
this.label = "";
}
then I get the error:
expression must have class type but it has type "N::Vec3D *"
This is my class definition:
#pragma once
#include <string>
namespace N {
class Vec3D
{
protected:
float x;
float y;
float z;
std::string label;
public:
//Constructors
Vec3D(float x, float y, float z);
Vec3D(float x, float y, float z, std::string label);
Vec3D();
void show();
};
}
I would like to know what the cause is of the generated error and how I can improve myself.
It's because this is a pointer. So you need to use it like this: this->x instead of this.x.
this is a pointer to the object, not a reference, nor is it a copy of the object. If an object is behind a pointer, one has to dereference it with the prefix * operator before accessing its members with the . operator; more typically though, one uses the -> operator to perform both at once. C++ inherited this syntax from C, which in turn has it for pretty tedious historical reasons. Although in case of this specifically, it’s often not even necessary to explicitly mention it from within member functions, as the usual scoping rules will happily resolve bare names to the respective data or function members.
Compare:
#include <iostream>
struct point {
float x;
float y;
void show() {
// member functions can access data members without
// explicitly referencing `this`
std::cout << "(" << x << ", " << y << ")" << std::endl;
}
};
void foo() {
point p { 1, 1 };
point &q = p;
point *r = &p;
// modifying p.x through a reference
q.x = 42;
// reading p.x through a pointer
std::cout << r->x << std::endl;
/* ↑↑↑↑ equivalent to (*r).x */
p.show(); // calling a member function on an owned value
q.show(); // calling a member function through a reference
r->show(); // calling a member function through a pointer
/* ↑↑↑↑↑↑↑↑↑ equivalent to (*r).show() */
}
In your example, this has type, Vec3D *, i.e. a pointer to Vec3D. As such, it has to be used like r above, if you use it at all.
this is a pointer to an object belonging to the method you are writing. You must dereference that pointer in order to access the opject. Once you access the object, you can then call a method with the dot operator. The -> operator is just a combo of the dereference operator (*) and the dot operator (.). Example:
Foo* foo = new Foo();
// This line
foo->bar();
// is equivalent to this line
(*foo).bar();
In the last line of the example, I first dereferenced the foo pointer with * to access the object. Then I used . to call a method on the object. The -> does both the dereferencing and the calling of the method.

C++ Passing an Object to a Member Function

For a homework assignment we are asked to create two classes: a MyPoint class and a ThreeDPoint class.
Here is my MyPoint class:
#pragma once
#include <math.h>
class MyPoint
{
private:
double x, y;
public:
MyPoint()
{
x = y = 0;
}
MyPoint(double x, double y)
{
this->x = x;
this->y = y;
}
double getX()
{
return x;
}
double getY()
{
return y;
}
double distance(MyPoint pointB)
{
return sqrt((x - pointB.x) * (x - pointB.x)
+ (y - pointB.y) * (y - pointB.y));
}
};
Here is my ThreeDPoint class:
#pragma once
#include "MyPoint.h"
class ThreeDPoint : public MyPoint
{
private:
double z;
public:
ThreeDPoint() // : MyPoint()
{
z = 0;
}
ThreeDPoint(double x, double y, double z) : MyPoint(x, y)
{
this->z = z;
}
double getZ()
{
return z;
}
double distance(ThreeDPoint pointB) // function overloading
{
// x and y are private not protected
return sqrt((getX() - pointB.getX()) * (getX() - pointB.getX())
+ (getY() - pointB.getY()) * (getY() - pointB.getY())
+ (getZ() - pointB.getZ()) * (getZ() - pointB.getZ()));
}
};
And here is main:
#include <iostream>
#include "SignatureBlock.h"
#include "MyPoint.h"
#include "ThreeDPoint.h"
int main()
{
SignatureBlock myBlock;
std::cout << myBlock.toString();
MyPoint pointA(1, 2);
MyPoint pointB(4, 2.5);
std::cout << pointA.distance(pointB) << '\n';
ThreeDPoint point_a(0, 0, 0);
ThreeDPoint point_b(10, 30, 25.5);
std::cout << point_a.distance(point_b) << '\n';
return 0;
}
This code works fine. It is able to calculate the distance between two points in both 2-dimensional and 3-dimensional space. However, in the homework instructions for the ThreeDPoint class, the book says to create
"A constant get function that returns the z value"
and
"A constant distance(const MyPoint&) function to return the distance between this point and the other point in three-dimensional space."
My question is what do they mean by "A constant get function..." and "A constant distance(const MyPoint&) function..."? I understand that you can put const after a function declaration to prevent the function from changing any class members, but why is this necessary here?
Also, why would I pass const MyPoint& to the distance function rather than a ThreeDPoint object? After all we're trying to find the distance between two ThreeDPoints. I read that if you have a parent object parameter in the member function declaration any child of that parent can also be passed to the function, so maybe that has something to do with it.
Lastly, isn't the distance(const MyPoint&) in the instructions missing a name for the MyPoint& object? I did try to type this in and the compiler doesn't mind, but how would I access the members of the object being passed in?
Edit: Also, what purpose does the & serve?
Most importantly, how would I re write my code to follow exactly what the instructions state?
Thanks for reading and thank you for any suggestions anyone might have.
If you live in a world where there are no const objects, it's never necessary to mark methods const. However, it is a good idea. Using const pointers and references is a very good practice when you don't need to change members of an object, and it can help you find design flaws when your program gets bigger.
It's also a good practice to pass references to objects, because passing a reference is usually faster than passing a copy of the object. (It's also in this context that you'll use const references: it tells the caller that you want the object by reference because it's faster, not because you want to change it.)
It's legal to omit argument names, but it has the obvious consequence that you won't be able to use them in your function. It's also a common notation because compilers get rid of argument names when they create function signatures, so you'll often see error messages that look like distance(const MyPoint&) instead of distance(const MyPoint& point).
I can't help you about why they want a const MyPoint& for the ThreeDPoint class. My best guess is that they want you to assume the z component of that point is 0.

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.

What is the best way to indicate that a double value has not been initialized?

I have a class CS which is to represent the co-ordinate system in 3D i.e.(x, y, z)
class CS
{
private:
double x;
double y;
double z;
}
CS::CS()
{
x = NULL;//this causes x = 0//i want the address of x to be 0x000000 & not x = 0
y = NULL;
z = NULL:
}
I want that the user can create a CS (0, 0, 0).
In the constructor i want to initialise the address of x, y & z to NULL.
this is to differentiate between the user defined (0, 0, 0) & the default value.
I am creating the objects of CS dynamically, so there is no point in using the following code:
class CS
{
private:
double *x;
double *y;
double *z;
}
CS:CS()
{
x = new double;
x = NULL;
//same for y & z
}
Primarily, i want to manually assign 0x000000 address to any variable(int or double or char) without using pointers.
any suggestions?
You can't change the positions of x,y,and z to be NULL, since there positions will always be offsets from the CS object. They will always exist. It's not that CS has an x like you have a car, it's like CS has an x like you have a head. You can't not have a head. If they were integers, you would have to make them pointers (like you said you didn't want to do), because that would be the only way to tell uninitialized from initialized. However, doubles have a magic value that is rarely used:
CS:CS()
: x(std::numeric_limits<double>::quiet_NaN())
: y(std::numeric_limits<double>::quiet_NaN())
: z(std::numeric_limits<double>::quiet_NaN())
{ }
Users probably won't be setting x, y, and z to (NOT A NUMBER) intentially.
Primarily, i want to manually assign 0x000000 address to any variable(int or double or char) without using pointers. any suggestions?
That's not what you want. What you want is the ability to detect whether a variable has been set or not.
Others have suggested things like using a specific floating-point value to detect the uninitialized state, but I suggest employing Boost.Optional. Consider:
class CS
{
private:
boost::optional<double> x;
boost::optional<double> y;
boost::optional<double> z;
}
boost::optional either stores the type you give to the template parameter or it stores nothing. You can test the difference with a simple boolean test:
if(x)
{
//Has data
}
else
{
//Has not been initialized
}
The downside is that accessing the data is a bit more complex:
x = 5.0; //Initialize the value. x now has data.
y = 4.0 * x; //Fails. x is not a double; it is an optional<double>.
y = 4.0 * (*x); //Compiles, but only works at runtime if x has a value.
You have several options:
Use pointers.
Use a boolean flag alongside each variable indicating whether the variable has been set.
If the range of allowable values is limited, you could use a special value to stand for "not set". For double, a not-a-number is often a natural candidate. For int and char it's often more tricky to pick a good value.
None of these options is indisputably better than the other two as they involve different tradeoffs. Take your pick.
Why can't you simply do this:
class CS
{
public:
// Constructs a CS initialized to 0, 0, 0
CS() : x(0), y(0), z(0), is_initialized(false) {}
// User defined values
CS(double newX, double newY, double newZ) : x(newX), y(newY), z(newZ), is_initialized(true) {}
private:
double x;
double y;
double z;
// If you need to know that this was initialized a certain way, you could use this suggestion from the comments:
bool is_initialized;
}
If I understand correctly, you want to be able to tell the difference between an invalid, default constructed CS and a valid one with values (0.0, 0.0, 0.0). This is exactly what boost::optional http://www.boost.org/doc/libs/1_47_0/libs/optional/doc/html/index.html is for.
You can't really represent it in the same number of bits without having a sentinel. If 0 is a valid number, then you can't use it. If you try and foist null handling into a value type you will have fundamentally incorrect and unmaintainable code.
When handling nulls properly you would expect to see an interface like this:
struct foo {
virtual ~foo() {}
virtual bool getX(double &val) = 0;
virtual bool getY(double &val) = 0;
virtual bool getZ(double &val) = 0;
};
The implementation can have a flag that it checks before access.
void some_func(foo *f) {
double x, y, z;
if (f->getX(x) && f->getY(y) && f->getZ(z)) {
cout << x << ", " << y << ", " << z << endl;
} else {
throw std::logic_error("expected some values here");
}
}
You don't want to use an invalid value and not know it. Having to check the return values is tedious obviously, but it gives you the most control. You could also have helpers or overloads that would throw if they weren't valid.
struct bar {
double getX() {
if (!valid)
throw std::logic_error("bar is not valid");
return x;
}
bool valid;
double x, y, z;
}
For me, the difference between foo and bar is that low level code handling the data shouldn't enforce a policy of whether the data is there or not. At higher levels of abstraction you can and should have expectations of whether the data should valid when you go to use it. The both can exist in a system, but foo is necessary.
One way to get the semantics of what you want would be to have the datatype of the coordinates be a type that carries with it a value indicating whether it has been assigned. Something like this.
template<typename T>
class CoordinateValue {
public:
CoordinateValue() : uninitialized(true), val(0) {}
CoordinateValue(T x) : uninitialized(false), val(x) {}
void setVal(T x) {val = x; uninitialized= false}
// Trivial getters
private:
T val;
bool uninitialized;
};
I'd prefer something like this over cuter methods unless memory is really scarce for some reason.
If the coordinates are either all default or all set, then you can have a single flag rather than a coordinate datatype that includes the flag.
I want that the user can create a CS (0, 0, 0). In the constructor i
want to initialise the address of x, y & z to NULL. this is to
differentiate between the user defined (0, 0, 0) & the default value.
I am creating the objects of CS dynamically, so there is no point in
using the following code:
This is the problem. Firstly, default value? What default value? Why should there be a default value? That's wrong. And secondly, it's fundamentally impossible for you to change the address of any variable.
What you want cannot be done and even if it could, it would be a horrendously bad idea.
You can't change the address of a variable. And you can't assign pointer values (like NULL, or nullptr in C++) to a variable of a non-pointer type, such as double.

Invalid use of class in C++?

hi im trying to pass some values to a class but it wont let me it says invalid use of class 'Figure' im trying to send 3 values x,y,z and thats all but it wont let me heres what im trying to do...
here is the main.cpp and the function that calls the class Figure
for (j = 0; j < num_elems; j++) {
/* grab and element from the file */
vlist[j] = (Vertex *) malloc (sizeof (Vertex));
ply_get_element (ply, (void *) vlist[j]);
int vert=sprintf(szFile,"vertex: %g %g %g", vlist[j]->x, vlist[j]->y, vlist[j]->z);
/* print out vertex x,y,z for debugging */
TextOut(hDC,600,j*20,szFile,vert);
DrawFig->Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
}
The error is here
DrawFig->Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
}
Here is the WM_CREATE: where i initialize everything
case WM_CREATE:
hDC = GetDC(hWnd);
//ShowWindow(g_hwndDlg,SW_SHOW);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
g_hwndDlg = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hWnd,DialogProc);
DrawFig= new Figure(1.0,1.0,1.0);
initGL();
break;
here is the Figure.h
class Figure
{
public:
Figure(float x,float y,float z);
void Draw();
float paramx(){
return x1;
}
float paramy(){
return y1;
}
float paramz(){
return z1;
}
protected:
private:
float x1,y1,z1;
list <Figure> m_vertices;
};
and here is the Figure.cpp
Figure::Figure(float x,float y,float z){
this->x1=x;
this->y1=y;
this->z1=z;
m_vertices.push_back(Figure(x1, y1, z1));
}
void Figure::Draw()
{
list<Figure>::iterator p = m_vertices.begin();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0,0.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0);
glColor3f(0.7f,1.0f,0.3f);
glBegin(GL_LINE_LOOP);
while(p != m_vertices.end()){
glNormal3f(p->paramx(),p->paramy(),p->paramz());
glVertex3f(p->paramx(),p->paramy(),p->paramz());
p++;
}
glEnd();
}
any ideas? this is opengl,c++ and im using codeblocks 10.05 just in case
oh yeah im initializing it at the main.h like this DrawFig* Figure;
#dark_charlie's answer is almost correct. Here is a better version that will actually work, but still probably isn't what you want:
class Figure {
// ...
public:
void set(float x, float y, float z);
// ...
};
void Figure::set(float x, float y, float z)
{
// Your original code from the constructor
this->x1 = x;
this->y1 = y;
this->z1 = z;
}
Figure::Figure(float x, float y, float z)
{
// In the constructor call the newly created set function
set(x, y, z);
m_vertices.push_back(Figure(x1, y1, z1));
}
// Replace the faulty line with this:
DrawFig->set(vlist[j]->x, vlist[j]->y, vlist[j]->z);
Now, this is almost certainly not what you want. But it's also really hard to figure out what you do want. You have a design problem. The design problem is that Figure has two responsibilities. It is both a point in space, and a set of points describing a figure. This confusion of responsibilities is leading your class to not actually be able to fill either of them particularly well.
You need two classes. You need a Point class and a Figure class. The Figure class should allow you to set the location of the figure as well as letting you add points to the figure's outline.
The huge clue that something is wrong is this list<Figure> m_vertices;. It's very rare that a class conceptually contains instances of itself. And usually when you do it you're building your own data structure like a tree or a list and then the class contains pointers to instances of itself.
Also, the fact that #dark_charlie's simple fix resulted in infinite recursion is another huge clue that something is wrong.
I'm guessing this is a homework assignment, so this is all the help I will give you aside from telling you that I think you already have a Point class that you call Vertex.
Just about the direct constructor call:
Use this instead:
// destruct and reconstruct
DrawFig -> ~Figure();
new (DrawFig) Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
What it does:
It calls the destructor.
The destructor itself will call the destructor of all member variables. floats don't need/have a destructor but std::list has. std::lists destructor will free all containing objects.
It calls the constructor.
The constructor itself will call the constructor of all member variables. Again, floats don't have that and they are not initialized in a specific way, i.e. they are ignored again. Then the constructor of std::list is called which will initialize the list.
However, using dark_charlie's solution might be more clean.
Not only is DCs solution more clean, it also does something different. By calling the constructor again, you would also reset Figure::m_vertices and I think this is probably not what you want here.
However, maybe instead of set (like in DCs solution) you should name it add or so instead.
Also I am not sure if you really want to have Figure or Figure::m_vertices that way (each Figure containing a list to other Figures).
You cannot call a constructor directly in the way you attempt to. Create a set() function that will do the same work and use it instead of the constructor:
class Figure {
// ...
public:
void set(float x, float y, float z);
// ...
};
void Figure::set(float x, float y, float z)
{
// Your original code from the constructor
this->x1 = x;
this->y1 = y;
this->z1 = z;
// m_vertices.push_back(Figure(x1, y1, z1));
}
Figure::Figure(float x, float y, float z)
{
// In the constructor call the newly created set function
set(x, y, z);
}
// Replace the faulty line with this:
DrawFig->set(vlist[j]->x, vlist[j]->y, vlist[j]->z);
EDIT:
As noted in the comments, the code has yet another flaw - you have a list of figures that is contained within the Figure itself. I think you meant to declare m_vertices as follows:
list <Vertex> m_vertices;
Then, however, if you want a Figure to be a triangle (or any other higher-order polygon), you will need to pass coordinates of all three vertices instead of the three coordinates of one vertex:
void Figure::set(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
m_vertices.push_back(v1);
m_vertices.push_back(v2);
m_vertices.push_back(v3);
// The position of the figure will be its centroid
this->x1 = (v1.x + v2.x + v3.x) / 3;
this->y1 = (v1.y + v2.y + v3.y) / 3;
this->z1 = (v1.z + v2.z + v3.z) / 3;
}
Figure::Figure(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
set(v1, v2, v3);
}
You will also need to adjust the loop to read 3 vertices at once instead of only one but I'll let that up to you :)
A few things:
Did you instantiate the Figure class?
Is the list <Figure> m_vertices; instantiated?
The usage of using C's malloc function with the C++ runtime code is messy, best to stick with new instead to keep the C++ runtime consistent.