Could not find a clear solution for this problem.
I have two classes Point and Vector. Vector is a child of Point In one of the methods of class Point I want to use an object of class Vector. I do it like this:
class Point
{
double x, y, z;
public:
// constructor from 3 values
Point(double x, double y, double z)
: x(x), y(y), z(z)
{}
// method move point
Point move(Vector vect, double dist)
{
Vector vectU = vect.unit();
return sum(vectU.multiplyScalar(dist));
}
};
class Vector: public Point
{
double x, y, z;
public:
// constructor from 3 values
Vector(double x, double y, double z)
: Point(x, y, z), x(x), y(y), z(z)
{}
// create unit vector
Vector unit()
{
double len = length();
return Vector(x / len, y / len, z / len);
}
};
When I compile this it gives me an error in line Point move(Vector vect, double dist) "Vector" has not been declared. I cannot find any useful answer for this error. How do I do this initialisation?
In C++ a class needs to be declared before it is defined. In your example with everything in one file, it has no idea what a Vector is when you define your Point::move function.
Typically, we'd have a header file per class (MyClass.h etc) and put the function definitions in a cpp file per class (MyClass.cpp)
So you need to restructure to something like:
Point.h:
#ifndef _POINT_H
#define _POINT_H
class Vector; // Forward declaration so you don't need to include Vector.h here
class Point
{
double x, y, z;
public:
// constructor from 3 values
Point(double x, double y, double z);
// method move point
Point move(Vector vect, double dist);
}
#endif // _POINT_H
Point.cpp
#include "Point.h"
#include "Vector.h"
// constructor from 3 values
Point::Point(double x, double y, double z)
: x(x), y(y), z(z)
{}
// method move point
Point Point::move(Vector vect, double dist)
{
Vector vectU = vect.unit();
return sum(vectU.multiplyScalar(dist));
}
Vector.h
#ifndef _VECTOR_H
#define _VECTOR_H
#include "Point.h"
class Vector: public Point
{
double x, y, z;
public:
// constructor from 3 values
Vector(double x, double y, double z)
: Point(x, y, z), x(x), y(y), z(z);
// create unit vector
Vector unit();
}
#endif // _VECTOR_H
Vector.cpp
#include "Vector.h"
// constructor from 3 values
Vector::Vector(double x, double y, double z)
: Point(x, y, z), x(x), y(y), z(z)
{}
// create unit vector
Vector Vector::unit()
{
double len = length();
return Vector(x / len, y / len, z / len);
}
(disclaimer, No guarantees that this will compile and work straight away, this is just to demonstrate how the code should be split up!)
Put a forward declaration:
class Vector;
at the beginning of the file.
Also, put a ; after the definition of each class.
If your class Vector
class Vector: public Point
inherits from Point, then you should not be using Vector in the base class Point (the base class shouldn't know anything about the derived class).
Also you are redefining x, y, z in your derived class Vector, which defeats the point of inheritance and can lead to very nasty behaviour when using polymorphism.
A virtual function may do the trick for you.
ie
move() Stub in the base
move() declaration in the derived.
Use pointers for dynamic binding.
eg point *x = new vector(...)
x.move()
etc etc.
Related
.h file
public:
Class(int x, int y); //constructor for this question
private:
char (*1dArrayObjectPtr)[size] = nullptr;
char nameof2dArray[notImportantX][size];
What is the difference between initializing Class (*1dArrayObjectPtr)[size] = nullptr; then assigning by:
cpp file
Class::Class(int x, int y) : x(x), y(y) {1dArrayObjectPtr = nameOf2dArray;};
or:
Class::Class(int x, int y) : x(x), y(y), 1DArrayObjectPtr(nameof2dArray) {};
Why does the top option result in segmentation faults and the bottom does not when I access as:
*(*(1DArrayObjectPtr+i)+j)
or
1DArrayObject[i][j]
If I pass 1DArrayObjectPtr to a new class will I be able to iterate the same?:
newClass::newClass(char* 1DArrayObjectPtr) : newClassPtr(1DArrayObjectPtr) {};
iterate as *(*(newClassPtr+i)+j) or newClassPtr[i][j]
Or am I changing the 1dpointer from the 2D array into something else and not realizing?
Scheff has confirmed semantically, there is no difference. I will look to my constructors for the base class to see if they could be culprit. Thanks Scheff. I tried to mark your comment as a solution, but I may have flagged it by mistake.... :D
Just like I'm creating member variables for x, y, and theta, how would I create member variables for the type vector<double> in the constructor? What I'm doing below doesn't seem to work.
Positioning::Positioning(double x, double y, double theta) {
this->globalX = x;
this->globalY = y;
this->globalTheta = theta;
vector<double> this->xs;
}
I have done #include <vector> and have std::vector<double> xs; in the private section of Positioning.hpp
EDIT
Header file:
namespace Position {
class Positioning {
private:
double globalX;
double globalY;
double globalTheta;
std::vector<double> xs;
public:
Positioning(double x, double y, double theta);
~Positioning();
void updateGlobalPosition(double left_dist, double right_dist, double rear_dist);
double getX();
double getY();
double getTheta();
};
}
This works
Positioning::Positioning(double x, double y, double theta) {
this->globalX = x;
this->globalY = y;
this->globalTheta = theta;
}
All your class variables are created automatically, you don't have to do anything special to create them.
The code in the body of the constructor above is not creating anything, it's assigning values to your variables. Of course if you want to give a member variable a particular value, then you have to do something, but they get created automatically.
I'm asking this question like this because I don't know how to phrase it better.
Right now, I'm writing a 3D-Application using the Eigen library. Eigen only has a Vector class, but I need distinct vector and point data types.
Both can be represented by an
Eigen::Vector4d(x,y,z,w)
where w is 1 for a point and 0 for a vector.
I know that I can define a type by using
typedef vec3d Eigen::Vector4d
or
#define point3d Eigen::Vector4d
but is there a way to define it in a way so that w is always going to be 0 for a vector and 1 for a point?
typedef vec3d(x,y,z) Eigen::Vector4d(x,y,z,w)
doesn't work.
You can inherit from it and provide a new constructor:
struct vec3d : Eigen::Vector4d {
vec3d(double x, double y, double z) : Vector4d(x, y, z, 0) {}
};
Or, what I would prefer, is to write a factory function like:
Eigen::Vector4D make_vector(double x, double y, double z) {
return {x, y, z, 0};
}
I cannot seem to find why I am getting the build error
expected primary-expression before "float"
In this implementation...
using namespace std;
class Point{
public:
Point(float X = 0.0, float Y = 0.0);
void set(float X, float Y);
void setX(float X);
void setY(float Y);
void get(float * P_x, float * P_y);
float getX();
float getY();
float * pX();
float * pY();
SDL_Point returnSDL();
private:
float x;
float y;
};
class Vector : public Point{
public:
Vector(float X = 0.0, float Y = 0.0);
};
///The errors occur in this constructor...
Vector::Vector(float X, float Y) : Point(float X, float Y){
}
Im still learning about the finer points of classes and would appreciate any help. I know it has something to do with the inheritance because when Vector doesn't inherit Point the program builds normally. As far as i can tell this is the correct syntax and implementation of inheritance. Web help i have found cannot answer so far.
///The errors occur in this constructor...
Vector::Vector(float X, float Y) : Point(float X, float Y){
}
There are two similar constructions in this fragment of code:
Vector::Vector(float X, float Y) and : Point(float X, float Y):
the first one (Vector::Vector(float X, float Y)) is the declaration of the constructor of class Vector;
the other one (: Point(float X, float Y)) is a function call; a call of the constructor of class Point; notice the colon (:) that introduce the list of member initializers.
Now, if you see the difference between the two (function/method declaration or definition vs. function/method call) you can find the error yourself: the compiler expects expressions and not types in the arguments list of the call to the Point::Point() constructor.
// Look, ma! No errors!
Vector::Vector(float X, float Y) : Point(X, Y) {
}
For more information take a look at the documentation page about constructors and member initializer lists.
You are confusing declaring a function and using a function. When you declare a function you need to tell the compiler what the types of the parameters are.
Vector::Vector(float X, float Y)
Now in the member initialization part you have
: Point(float X, float Y)
Here you are adding types to the function call which is not what you want to do. When you call a function you just pass the values/variables to it.
: Point( X, Y)
^ ^ no type here as we just pass X and Y to the Point constructor.
Been banging my head against this all day with many trips to google.
I have a master object that needs to create several other objects in its constructor the main object gets variables in its constructor that are passed on to the objects it creates.
class WorldManager{
public:
WorldManager(int x, int y, int z){
//do stuff
}
}
class GameManager{
public:
WorldManager world;
GameManager(int x, int y, int z){
world(x,y,z);
}
}
I get error
error: no matching function for call to `GAMEMANAGER::GraphicsManager(HWND__*&, int&, int&)'
it works untill I ask for args in the constructors of the world class
I think that you want:
class GameManager{
public:
WorldManager world;
GameManager(int x, int y, int z) : world(x, y, z) { }
};
The weird colon thing is called an initialization list, and it does construction of member objects and parent classes and a bunch of other things.
If you have more than one object that you want to construct, add them to the list:
class GameManager{
public:
WorldManager world1, world2;
GameManager(int x, int y, int z) : world1(x, y, z), world2(x, y, z) { }
};