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
};
Related
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;
};
It is the code which I cannot figure out why it is not working the way I want, I look around the internet, but did not some good solution.
Point class:
class Point
{
public:
Point(const Point &) {
cout << "copy constructor was called" << endl;
}
Point(int x, int y) : x(x), y(y) {
}
void setX(int x) {this->x = x;}
void setY(int y) {this->y = y;}
int getX() const { return x; }
int getY() const { return y; }
private:
int x;
int y;
};
Circle class:
class Circle
{
private:
int rad;
Point &location;
public:
Circle(int radius, Point &location) : rad(radius), location(location) {}
int getRad() { return rad; }
Point & getLocation() { return location; }
};
The usage:
int main() {
Point p(23, 23);
Circle c(12, p);
Point p1 = c.getLocation();
p1.setX(200);
cout << p.getX() << endl; // prints 23, which I want to be 200
// copy constructor was called
system("pause");
return 0;
}
In the following line:
Point p1 = c.getLocation();
p1 is not a reference, so basically you're copying the referenced object returned by getLocation(), thus calling copy constructor.
A solution would be to declare p1 as a reference like this:
Point& p1 = c.getLocation();
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) {}
// ...
};
I am currently rewriting C code into C++ code. While doing that I am replacing structs with classes. That means that some of the variables go from public to private. Now during the transition phase I want to do some error checking by compiling the program sometimes and running it. Thus I intended to have public and private variables at the same time, which are linked, i.e. when I write something into the private variable, the public variable also changes. Nevertheless I only want to write to the private variables by using separate functions, i.e. having the public variables as read-only variables. My current approach is:
#include <iostream>
#include <stdio.h>
class test_vec
{
private:
int x, y;
int data[2];
public:
int x_ext, y_ext;
int data_ext[2];
test_vec(int x, int y)
{
this->x = x;
this->y = y;
this->x_ext = this->x;
this->y_ext = this->y;
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
};
int main(void)
{
std::cout << "Hello World\n";
test_vec test(1, 2);
printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//So far, so good
test.set_x(4);
test.set_y(10);
printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//Not updated!
return 0;
}
How can I change the links between the variables? At the moment I already have two pointers copied into each other, but how can I "lock" the external variable onto the internal variable?
Not sure if it's a good design pattern since inline getters are fast but you could create constant references to your private variables:
class test_vec
{
private:
int x, y;
int data[2];
public:
const int &x_ext, &y_ext;
int data_ext[2];
// you have to initialize the references before constructor body
// references cannot be let uninitialized
test_vec(int x, int y) : x_ext(this->x), y_ext(this->y)
{
this->x = x;
this->y = y;
}
~test_vec()
{}
inline void set_x(int x)
{
this->x = x;
}
inline void set_y(int y)
{
this->y = y;
}
};
when x or y changes x_ext and y_ext follow:
Hello World
test has the properties (1, 2)
test has the properties (4, 10)
Bonus: constant references cannot be modified. That's the closest thing of a read property that you got here :)
If you don't want that restriction, just remove the const qualifier, but since you're encouraging encapsuation now that you have C++ I would let it as is and let the writers hit the wall on that (not to mention a good sed/regex replacement could refactor all your writes automatically)
You can use references for these purposes.
Say you have this setup:
class myclass{
public:
myclass(int pa, float pb);
int get_a() const {return a;}
float get_b() const {return b;}
void set_a(int v) {a=v;}
void set_b(float v) {b=v;}
private:
//These are the real values, private
int a;
float b;
public:
//These are the references, public
int& ref_to_a;
float& ref_to_b;
}
myclass::myclass(int pa, float pb)
:a(pa), b(pb), ref_to_a(a), ref_to_b(b)
{
}
You can go like this:
myclass c(33, 12.3f);
c.set_a(12);
c.set_b(111.1f);
//This...
std::cout<<c.ref_to_a<<" "<<c.ref_to_b<<std::endl;
//Should be the same as this...
std::cout<<c.get_a()<<" "<<c.get_b()<<std::endl;
Notice the access settings: the references are public, meaning you can write and read from them. If you want them to be read only you can play with the constness.
I wouldn't bother. Just make the members public for the moment, and when you have fixed all the external references, make them private.
class test_vec
{
public: // For now. Will become private later
int x, y;
public: // For now.
int data[2];
public: // For ever
test_vec(int x, int y)
: x(x), y(y) // Prefer initialization to assignment.
{
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
int get_x() const { return x; } // etc
};
If you really wanted to, you could make x_ext be a reference to const - but it's much more idiomatic in C++ to make getters be functions.
class test_vec
{
private:
int x, y;
int data[2];
public:
int const& x_ext;
int const& y_ext;
test_vec(int x_, int y_)
: x(x_), y(y_)
, x_ext(x), y_ext(y) // You *have* to use initialization here.
{
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
};
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;
}