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.
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.
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.
I want to make a function, and in different contexts it is better called by different names.
class box(){
private:
float posX;
float size = 10;
public:
float speedX;
float left(){ return posX; } //Any way to combine these?
float posX(){ return posX; } //Any way to combine these?
float right(){ return posX + size; }
};
box a;
box b;
bool checkCollide(){
if(a.right() < b.left()){ return 0; } //Not colliding
if(b.right() < a.left()){ return 0; } //Not colliding
return 1; //Colliding
} //Comparing right and left makes more sense than anything else
void physics(){
a.posX() += a.speedX;
b.posX() += b.speedX;
//Adding speed to position makes more sense than
//adding speed to "left"
}
//Loop physics X times per second, and do something if there's a collision
or, is there a better way to do this? Can I make the left/right member automatically update any time the position or size changes, instead of recalculating for every call?
If you are really obliged to do this, then just make the one function call the other:
// the function that does the hard job
float foo(float a, float b)
{
// some heavy and complicated code
// ...
// some more black magic, etc.
// finally:
return sqrt(a * a + b * b);
}
// the function that pretends to do the hard job
float bar(float a, float b)
{
return foo(a, b);
}
But you better not do this, it's quite bad style. Different names => different tasks. Same task => same name. Don't hurt the intuition of your fellows... ;-)
Yes - Not write two functions that at the start do the same thing. I just hope that they do not diverge. Then you have problems!
If you're on C++11, or when using Boost, you can bind the left() function to an std::function variable. With C++11:
class box {
// ...
public:
// ...
float left() { return posX; }
const std::function<float()> posx = std::bind(&box::left, this);
The const is needed, otherwise posx could be changed at runtime to point to a different function.
If you're not using a C++11 compiler but use Boost instead, then it's not that expressive, since you have to initialize posx in the ctor:
class box {
// ...
public:
box() : posx = boost::bind(&box::left, this);
// ...
float left() { return posX; }
const boost::function<float()> posx;
In both cases, you can now do:
box b;
b.left();
b.posx();
This method doesn't really have any advantages I can think of compared to having a posx() function and calling left() in it. But it's possible and so deserves a mention.
But I agree with what H2CO3 said: don't have two names for the same function. It's confusing.
The following code throws the aforementioned error message at the line where an object is added to a vector:
include "palm.h"
include <vector>
using namespace std;
class forehead {
public:
void palmstrikesforehead(float x, float y, float z);
private:
vector<palm> palms;
};
void forehead::palmstrikesforehead(float x, float y, float z) {
Palm::Palm palm(x,y,z);
palms.push_back(palm); //Exception thrown if this line is not commented out.
}
The code works with a vector of integer type, but not with a vector of Palm type. What I would like to do is to anonymously add Palms to the vector (as in the java: arrayList.add(new Palm(x,y,z));. How may that be done?
The class name seems to be palm. So you should write
palm the_palm (x, y, z);
//^^^^
palms.push_back(the_palm);
Or you could construct the palm in-place:
palms.push_back(palm(x, y, z));
If Palm is the correct class name (you don't get a compile error), then Palm::Palm palm(x,y,z); should be Palm palm(x,y,z);
class forehead {
public:
void palmstrikesforehead(float x, float y, float z);
private:
vector<Palm::Palm> palms;
};
This is not possible to solve at present as we don't know what is in Palm never mind what it's called.
Assuming that Palm is your own class, there is potentially an issue with your copy-constructor. Is your class obeying the "rule of 3"?
To "anonymously add", assuming your class is called palm, you would do:
palms.push_back( palm(x,y,z) );