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.
Related
I have a 2d physics engine that I've been programming in C++ using SFML; I've implemented a rough collision detection system for all SandboxObjects (the base class for every type of physics object), but I have a dilemma.
I plan to have many different derived classes of SandboxObjects, such as Circles, Rects, and so on, but I want a way to check if the roughHitbox of each SandboxObject collides with another.
When the program starts, it allocates memory for, let's say, 10,000 Circles
int circleCount = 0;//the number of active Circles
constexpr int m_maxNumberOfCircles = 10000;//the greatest number of circles able to be set active
Circle* m_circles = new Circle[m_maxNumberOfCircles];//create an array of circles that aren't active by default
like so.
and every time the user 'spawns' a new Circle, the code runs
(m_circles + circleCount)->setActive();`
circleCount++
Circles that aren't alive essentially do not exist at all; they might have positions and radii, but that info will never be used if that Circle is not active.
Given all this, what I want to do is to loop over all the different arrays of derived classes of SandboxObject because SandboxObject is the base class which implements the rough hitbox stuff, but because there will be many different derived classes, I don't know the best way to go about it.
One approach I did try (with little success) was to have a pointer to a SandboxObject
SandboxObject* m_primaryObjectPointer = nullptr;
this pointer would be null unless there were > 1 SandboxObjects active; with it, I tried using increment and decrement functions that checked if it could point to the next SandboxObject, but I couldn't get that to work properly because a base class pointer to a derived class acts funky. :/
I'm not looking for exact code implementations, just a proven method for working with the base class of many different derived classes.
Let me know if there's anything I should edit in this question or if there's any more info I could provide.
Your problems are caused by your desire to use a polymorphic approach on non-polymorphic containers.
The advantage of a SandboxObject* m_primaryObjectPointer is that it allows you to treat your objects polymorphicaly: m_primaryObjectPointer -> roughtHitBox() will work regardless of the object's real type being Circle, Rectangle, or a Decagon.
But iterating using m_primaryObjectPointer++ will not work as you expect: this iteration assumes that you iterate over contiguous objects in an array of SandboxObject elements (i.e. the compiler will use the base type's memory layout to compute the next address).
Instead, you may consider iterating over a vector (or an array if you really want to deal with extra memory management hassle) of pointers.
vector<SandboxObject*> universe;
populate(universe);
for (auto object:unviverse) {
if (object->isActive()) {
auto hb = object -> roughtHitBox();
// do something with that hitbox
}
}
Now managing the objects in the universe can be painful as well. You may therefore consider using smart pointers instead:
vector<shared_ptr<SandboxObject>> universe;
(little demo)
It's hard to answer this without knowing the requirements but you could have sandbox maintain two vectors of active and inactive objects, and use unique_ptrs of the base class for memory management.
Some code below:
#include <vector>
#include <memory>
#include <iostream>
class sandbox_object {
public:
virtual void do_something() = 0;
};
class circle : public sandbox_object {
private:
float x_, y_, radius_;
public:
circle(float x, float y, float r) :
x_(x), y_(y), radius_(r)
{}
void do_something() override {
std::cout << "i'm a circle.\n";
}
};
class triangle : public sandbox_object {
private:
float x1_, y1_, x2_, y2_, x3_, y3_;
public:
triangle( float x1, float y1, float x2, float y2, float x3, float y3) :
x1_(x1), y1_(y1), x2_(x2), y2_(y2), x3_(x3), y3_(y3)
{}
void do_something() override {
std::cout << "i'm a triangle.\n";
}
};
class sandbox {
using sandbox_iterator = std::vector<std::unique_ptr<sandbox_object>>::iterator;
private:
std::vector<std::unique_ptr<sandbox_object>> active_objects_;
std::vector<std::unique_ptr<sandbox_object>> inactive_objects_;
public:
void insert_circle(float x, float y, float r) {
active_objects_.push_back( std::make_unique<circle>(x, y, r) );
}
void insert_triangle(float x1, float y1, float x2, float y2, float x3, float y3) {
active_objects_.push_back( std::make_unique<triangle>(x1,y1,x2,y2,x3,y3));
}
sandbox_iterator active_objs_begin() {
return active_objects_.begin();
}
sandbox_iterator active_objs_end() {
return active_objects_.end();
}
void make_inactive(sandbox_iterator iter) {
std::unique_ptr<sandbox_object> obj = std::move(*iter);
active_objects_.erase(iter);
inactive_objects_.push_back(std::move(obj));
}
};
int main() {
sandbox sb;
sb.insert_circle(10.0f, 10.0f, 2.0f);
sb.insert_triangle(1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 1.0f);
sb.insert_circle(1.0f, 6.0f, 4.0f);
sb.make_inactive(sb.active_objs_begin());
(*sb.active_objs_begin())->do_something(); // this should be the triangle...
return 0;
}
I am experimenting with a simple vertex class.
class Vertex
{
public:
std::vector<float> coords;
//other functionality here - largely irrelevant
};
And lets say we create a Vertex object as below:
Vertex v0(1.f, 5.f, 7.f);
I am wondering if there is anyway to assign a name to each element of a vector?
Let's say that each std::vector will only ever have a size of 3. I know I can access an element or index of the vector in a way such as v0.coords[0] through to v0.coords[2];
However, I am wondering if there is a way in which I could assign a name to each element of the vector, ie:
v0.coords.x == v0.coords[0];
v0.coords.y == v0.coords[1];
v0.coords.z == v0.coords[2];
So that if I was to access the vector, I could access via a name rather than an index.
Is such a thing possible? If so, how do I go about creating such aliasing?
I am wondering if there is anyway to assign a name to each element of a vector?
No, there is not. At least, not the way you want.
I suppose you could use macros, eg:
#define coords_x coords[0]
#define coords_y coords[1]
#define coords_x coords[2]
Now you can use v0.coords_x, v0.coords_y, and v0.coords_z as needed.
Or, you can use getter methods, eg:
class Vertex
{
public:
vector<float> coords;
//other functionality here - largely irrelevant
float& x(){ return coords[0]; }
float& y(){ return coords[1]; }
float& z(){ return coords[2]; }
};
Now you can use v0.x(), v0.y(), and v0.z() as needed.
But really, in this situation, there is just good no reason to use a vector at all. It is simply the wrong tool for the job. Use a struct instead, eg:
struct Coords
{
float x;
float y;
float z;
};
class Vertex
{
public:
Coords coords;
//other functionality here - largely irrelevant
};
Alternatively:
class Vertex
{
public:
struct
{
float x;
float y;
float z;
} coords;
//other functionality here - largely irrelevant
};
Now you can use v0.coords.x, v0.coords.y, and v0.coords.z as needed.
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).
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.
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]; }
};