Creating my own 'data type' - c++

I want to be able to create a type that has 3 floats (x,y,z). I have tried:
typedef struct
{
float x;
float y;
float z;
} Vertex;
But that didn't work.
Does this have to be declared somewhere where it can be seen by main? How would I go about creating getter methods and other methods for a type I have made?

How I'd do it in C++. See main() for example usage. N.B. This hasn't been compiled or tested.
#include <iostream>
class Vertex
{
public:
// Construction
Vertex(float x,float y, float z) : x_(x), y_(y), z_(z) {}
// Getters
float getX() const {return x_;}
float getY() const {return y_;}
float getZ() const {return z_;}
// Setters
void setX(float val) {x_ = val;}
void setY(float val) {y_ = val;}
void setZ(float val) {z_ = val;}
private:
float x_;
float y_;
float z_;
};
int main()
{
Vertex v(6.0f,7.2f,3.3f);
v.setZ(7.7f);
std::cout < "vertex components are " << v.getX() << ',' << v.getY() << ',' << v.getZ() << std::endl;
}

does this have to be declared somewhere where it can be seen by main?
Yes. Typically the class or struct is declared in a header file, which you #include in whatever translation unit (c file) you use it in.

Using C, this works for me
typedef struct { float x; float y; float z; } Vertex;
int main(void) {
Vertex a = {42, -42, 0};
if (a.x + a.y + a.z == 0) return 1; /* warning about comparing floating point values */
return 0;
}

Related

error C2248: 'point::x': cannot access private member declared in class 'point'

With this code:
#include <iostream>
using namespace std;
class point{
public:
double get_x();
void set_x(double v);
double get_y();
void set_y(double z);
private:
double x, y;
};
point operator+(point& p1, point& p2)
{
point sum = {p1.x};// + p2.x, p1.y + p2.y};
return sum;
}
int main()
{
point a = {3.5,2.5}, b = {2.5,4.5}, c;
}
I get the following compiler errors saying the private members cannot be accessed:
point.cpp(22): error C2248: 'point::x': cannot access private member declared in class 'point'
point.cpp(17): note: see declaration of 'point::x'
point.cpp(8): note: see declaration of 'point'
I am pretty new to C++ and can't seem to figure out how to resolve this issue. Any help is much appreciated.
You declared x and y as private so they can't be accessed in that function(or outside the class) unless you make that function a friend of the class, but if you want to overload the + operator, you should do it inside the class, something like this :
class point
{
public:
point(double x, double y) // CONSTRUCTOR
:x(x), y(y)
{
}
double get_x() const{
return x;
};
void set_x(double v)
{
x = v;
};
double get_y() const{
return y;
};
void set_y(double z)
{
y = z;
};
point operator+(const point &obj)
{
double newX = this->x + obj.get_x();
double newY = this->y + obj.get_y();
point sum{newX, newY};
return sum;
};
private:
double x, y;
};

'PointType’ is not a member of ‘Point’

I am getting a compilation error saying " ‘PointType’ is not a member of ‘Point’ " I do not know what I need to implement in my code. Been thinking for a while now. I've tried adjusting the codes here and there a few times. But could not think of a solution for this. I'm a little confused by what "Point point(Point::PointType(x, y), depth);" in the main() wants. What exactly is PointType(x,y)? Can anyone enlighten me with what I should do? Would appreciate anyone's help on this. Side Note: Main() can't be touched. Thanks!
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
struct PointType
{
float x;
float y;
PointType(const float x1, const float y1) :x(x1),y(y1){}
};
class Object
{
private:
float d;
PointType * pt;
public:
Object(float n) : d(n){}
float depth() const
{
return d;
}
};
class Point :public Object
{
private:
PointType mpoint;
public:
Point(const PointType& pt, float& y1) : mpoint(pt), Object(y1) {}
virtual ~Point();
};
Main file:
const float EPSILON = 1e-5f;
bool is_near(float x, float y)
{
return std::abs(x - y) < EPSILON;
}
float frand()
{
return 10.0f * float(rand()) / float(RAND_MAX);
}
int main()
{
srand(unsigned(time(0)));
int count = 0;
int max_count = 0;
float x = frand();
float y = frand();
float depth = frand();
Point point(Point::PointType(x, y), depth);
if (is_near(point.depth(), depth))
{
++count;
}
else
{
std::cout << " - Point::depth test failed" << std::endl;
}
++max_count;
}
You've got a set circular declarations that can't be resolved if you can't change main(). You currently have PointType as a struct outside of the Point class. That's fine, but then you need to change the line in main() from:
Point point(Point::PointType(x, y), depth);
to:
Point point(PointType(x, y), depth);
But if you can't do that, then you can't ever compile this because Point is a subclass of Object, but Object requires a Point::PointType which can't have been defined yet. In order to have PointType be owned by Point, you need to declare it like this:
class Point :public Object
{
struct PointType
{
float x;
float y;
PointType(const float x1, const float y1) :x(x1),y(y1){}
};
private:
PointType mpoint;
public:
Point(const PointType& pt, float& y1) : mpoint(pt), Object(y1) {}
virtual ~Point();
};
But once you put PointType into Point, you can't declare any member of Object to have a type of Point::PointType because Point inherits from Object.
You could declare Object::pt to be a void* but that throws away type information which is dangerous.

C++ class method call in .cpp without ::

I'm new to progamming in C++. I have a good background with Java but C++ is different on many things and I have a question about one of the regarding .h and .cpp files.
I have the following files for a point object with x and y position:
Point.h
#ifndef POINT_H_
#define POINT_H_
class Point{
Point();
Point(int newX, int newY);
public:
int getX();
int getY();
void setX(int newX);
void setY(int newY);
void moveBy(int moveX, int moveY);
Point reverse();
private:
int x;
int y;
};
#endif
Point.cpp
#include "Point.h"
using namespace Point;
Point::Point(int newX, int newY){
x = newX;
y = newY;
}
int Point::getX(){
return x;
}
int Point::getY(){
return y;
}
void Point::setX(int newX){
x = newX;
}
void Point::setY(int newY){
y = newY;
}
void Point::moveBy(int moveX, int moveY){
x += moveX;
y += moveY;
}
Point Point::reverse(){
return Point(y,x);
}
I was wondering if there was a way of avoinding the Point::Point part like with std::cout by using namespace.
Thank you
You aren't required to separate your declaration and definition, and these functions are incredibly trivial. So including them in the class definition may actually allow the compiler to perform numerous additional optimizations.
So you could discard the .cpp entirely and the header becomes:
#ifndef POINT_H_
#define POINT_H_
class Point
{
int x_ { 0 };
int y_ { 0 };
public:
Point() = default;
Point(int x, int y) : x_(x), y_(y) {}
int getX() const { return x_; }
int getY() const { return y_; }
void setX(int x) { x_ = x; }
void setY(int y) { y_ = y; }
void moveBy(int x, int y) { x_ += x, y_ += y; }
Point reverse() const { return Point(y_, x_); }
};
#endif
But you can't avoid the "Point::" part when defining the members outside of the class declaration.
If you want to avoid typing the "Point::" in front of the getX, getY etc., then the answer is "no", unfortunately. In C++ and the name of any class (like "Point") is not a namespace, it's a scope.
What you can only do is inlining the method, defining into the class declaration.
class Point {
public:
void a_method() {
// all the code here!
}
};
You can't avoid "the Point::Point part," unless you declare the construction inline in the class declaration. The first "Point" defines the scope of the function, and the second "Point" is the name of the constructor function.
However, you could define the constructor(s) inline, like so:
class Point
{
Point()
{
x = 0;
y = 0;
}
Point(int newX, int newY);
{
x = newX;
y = newY;
}
// ...
};
Or:
class Point
{
Point() : x(0), y(0) {}
Point(int newX, int newY) : x(newX), y(newY) {}
// ...
};
Or:
class Point
{
Point(int newX = 0, int newY = 0) : x(newX), y(newY) {}
// ...
};

Defining a unique function for each object

I have a class, along with it's objects. What do I do if I want each object to do something different? (AKA each object has a unique function).
Here is a simplified code of what I am trying to achieve.
The basic class
class Thing
{
private:
int x, y, z;
public:
static vector<Thing*> objects;
int getX() {return x;}
int getY() {return y;}
int getZ() {return z;}
Thing(int X, int Y, int Z)
{
this->x = X;
this->y = Y;
this->z = Z;
objects.push_back(this);
}
void func(); //THE EVENTUAL UNIQUE FUNCTION
};
vector<Thing*> Thing::objects = {};
My theoretical desired code
int main()
{
Thing A(1, 2, 3);
void A->func() //A REDEFINITION OF THE PUBLIC FUNCTION
{
cout << "do stuff" << endl;
}
}
Use std::function and C++11 lambdas
class Thing
{
private:
int x, y, z;
public:
static vector<Thing*> objects;
int getX() {return x;}
int getY() {return y;}
int getZ() {return z;}
Thing(int X, int Y, int Z)
{
this->x = X;
this->y = Y;
this->z = Z;
objects.push_back(this);
}
std::function<void()> func; //THE EVENTUAL UNIQUE FUNCTION
};
Redefine unique function
A.func = [&A]() {
// do something
};

How to use multiple names for class members in C++

So I have a vec4 class that uses members x,y,z,w which you can access using
point.x point.y etc.
However I want to reuse this vec4 class to be my color class (it already supports scalar multiplication, operator overloading lots of other nice stuff)
I just want to be able to refer to the members using another notation:
color.r
color.g
color.b
etc.
Is there anyway I can do this using a macro or other syntactic sugar?
If you are using Visual Studio (and are sure that it is the only target IDE...) you can use the following:
#include <cassert>
union vec4
{
struct
{
float x;
float y;
float z;
float w;
};
struct
{
float r;
float g;
float b;
float a;
};
};
int main()
{
vec4 vec = { 0 };
vec.y = 10.0f;
assert(vec.g == 10.0f);
return 0;
}
It will yield warnings warning C4201: nonstandard extension used : nameless struct/union, though you can disable it.
EDIT: as it turns out gcc supports this extension as well.
Unless you have a good amount of common behavior between a vector and a color I think this is a bad idea. But since you asked, here is a possible way to do that.
If you make the x, y, z and w members private and provide accessor methods to get to them, then it is easy to provide two alternative ways to refer to the same member variables. For example:
class vec4 {
private:
float _x, _y, _z, _w;
public:
// vector getter/setters
float& x() { return _x; }
float& y() { return _y; }
float& z() { return _z; }
float& w() { return _w; }
// color getter/setters
float& r() { return _x; }
float& g() { return _y; }
float& b() { return _z; }
float& a() { return _w; }
};
vec4 my_color;
my_color.r() = 1.0f;
my_color.g() = 0.0f;
my_color.b() = 0.0f;
my_color.a() = 1.0f;
You can easily do that with standalone accessor functions:
struct vec4 { double x, y, z; };
double& get_r(vec4& v) { return v.z; }
// and so on