no default constructor exists - c++

I'm having some trouble with a class that was working fine and now doesn't seem to want to work at all.
The error is "No appropriate default constructor available"
I am using the class in two places I'm making a list of them and initializing then adding them to the list.
Vertice3f.h
#pragma once
#include "Vector3f.h"
// Vertice3f hold 3 floats for an xyz position and 3 Vector3f's
// (which each contain 3 floats) for uv, normal and color
class Vertice3f{
private:
float x,y,z;
Vector3f uv, normal, color;
public:
// If you don't want to use a UV, Normal or Color
// just pass in a Verctor3f with 0,0,0 values
Vertice3f(float _x, float _y, float _z, Vector3f _uv,
Vector3f _normal, Vector3f _color);
~Vertice3f();
};
Vertice3f.cpp
#include "Vertice3f.h"
Vertice3f::Vertice3f(float _x, float _y, float _z,
Vector3f _uv, Vector3f _normal, Vector3f _color){
x = _x;
y = _y;
z = _z;
uv = _uv;
normal = _normal;
color = _color;
}
It is being using in my OBJModelLoader class as follows:
list<Vertice3f> vert3fList;
Vertice3f tvert = Vertice3f(
x = (float)atof(
vertList[i].substr(
vertList[i].find("v") + 1,
vertList[i].find(" ", vertList[i].find("v") + 2, 10)
).c_str()
),
y = (float)atof(
vertList[i].substr(
vertList[i].find(" ", vertList[i].find("v") + 4, 10) + 1,
vertList[i].find(" ", vertList[i].find("v") + 13, 10)
).c_str()
),
z = (float)atof(
vertList[i].substr(
vertList[i].find(" ", vertList[i].find("v") + 13, 10) + 1,
vertList[i].find(" ", vertList[i].find("v") + 23, 10)
).c_str()
),
::Vector3f(0.0f,0.0f,0.0f),::Vector3f(0.0f,0.0f,0.0f),::Vector3f(0.0f,0.0f,0.0f)
);
vert3fList.push_back(
tvert
);
I have tried defining a default constructor myself so in the .h I put
Vertice3f();
and in the cpp
Vertice3f::Vertice3f(){
x = 0.0f;
y = 0.0f;
z = 0.0f;
uv = Vector3f(0.0f,0.0f,0.0f);
normal = Vector3f(0.0f,0.0f,0.0f);
color = Vector3f(0.0f,0.0f,0.0f);
}
So, I'm not sure why it can't find a default constructor or how to appease the compiler. I'm sure it's user error because the compiler probably knows what it's doing.
Any help is greatly appreciated, I will answer any other questions you have, just ask.

I'd guess that the missing default constructor is the default constructor of Vector3f class, not of Vertice3f class. Your constructor of Vertice3f attempts to default-construct its Vector3f members, which leads to the error.
This is why your attempts to provide default constructor for Vertice3f don't change anything. The problem lies, again, with Vector3f.
To fix it either provide all necessary default constructors (assuming it agrees with your design), or rewrite the constructor of Vertice3f by using initializer list instead of in-body assignment
Vertice3f::Vertice3f(float _x, float _y, float _z,
Vector3f _uv, Vector3f _normal, Vector3f _color) :
x(_x), y(_y), z(_z), uv(_uv), normal(_normal), color(_color)
{}
This version no longer attempts to default-construct anything. And using initializer list instead of in-body assignment is a good idea in any case.

Related

Return my struct as an array in C++, OPENGL

I have a problem with my function. I can't seem to make it return an array of a struct.
Here is the MyApp.h header file:
struct Vertex
{
glm::vec3 p;
glm::vec3 c;
};
class CMyApp
{
public:
CMyApp(void);
~CMyApp(void);
Vertex[] DrawCircle(int cx, int cy);
...
It underlines the DrawCircle and "expects a ';'".
Here is the MyApp.cpp (Of course, header included):
Vertex[] CMyApp::DrawCircle(int cx, int cy) {
Vertex result[42];
result[0] = { glm::vec3((float)cx, (float)cy, 0.0), glm::normalize(glm::vec3(0, 0, 1)) };
for (int ii = 1; ii < 21; ii++) {
float theta = 2.0f * 3.1415926f * float(ii) / float(20);
float x = 0.5 * cosf(theta);
float y = 0.5 * sinf(theta);
result[ii].p = glm::vec3(x, y, 0.0);
result[ii].c = glm::normalize(result[ii].p);
}
result[21] = { glm::vec3((float)cx, (float)cy, 2.0), glm::normalize(glm::vec3(0, 0, 1.0)) };
for (int ii = 22; ii < 42; ii++) {
float theta = 2.0f * 3.1415926f * float(ii) / float(20);
float x = 0.5 * cosf(theta);
float y = 0.5 * sinf(theta);
result[ii].p = glm::vec3(x, y, 2.0);
result[ii].c = glm::normalize(result[ii].p);
}
return result;
}
Same underline here under the function name's DrawCircle for expected ";".
If I remove the array marks then the only error is the return statement. I want to return as an array tho.
Thanks for help in advance.
You cannot return a local array. Such an array is allocated on the stack; when the function returns, all its content is available for other stack variables. If you use it after the call, its content is likely to be corrupted.
So
Vertex[] CMyApp::DrawCircle(int cx, int cy) {
Vertex result[42];
return result;
}
is undefined behavior for the compiler.
You should use a vector instead. Its move constructor makes it efficient for returning many results organized as an array.
std::vector<Vertex> CMyApp::DrawCircle(int cx, int cy) {
std::vector<Vertex> result;
result.reserve(42);
// same content than your original code.
...
return result;
}
Note that if you declare
class CMyApp
{
public:
CMyApp(void);
~CMyApp(void);
typedef Vertex ArrayOfVertices[];
ArrayOfVertices DrawCircle(int cx, int cy);
};
You obtain the error message:
error: ‘DrawCircle’ declared as function returning an array
ArrayOfVertices DrawCircle(int cx, int cy);
I want to return as an array tho.
You can't. C and C++ don't allow it. What you can do in C++ is returning a std::vector which you should use instead of plain arrays anyway.

c++ crashes using frameworks, bad constructor

I am writing a simple animation to draw a ball bouncing off walls. Here is the class:
class Ball{
private:
int x,y; //position
int vx,vy; //velocity
int rad=20; //radius
ofColor color; //color
public:
Ball(int a, int b, int c, int d,ofColor e);
Ball();
void draw();
void move();
};
When I construct Ball with 5 arguments everything works fine, but it crashes when I use the one without arguments:
Ball::Ball(){
x=int(ofRandomWidth());
y=int(ofRandomHeight());
vx=int(ofRandom(-10,10));
vy=int(ofRandom(-10,10));
int r=int(ofRandom(0,255));
int g=int(ofRandom(0,255));
int b=int(ofRandom(0,255));
ofColor a(r,g,b);
color=a;
}
What can be wrong with this constructor?
ofRandom:
float ofRandom(float max) {
return max * rand() / (RAND_MAX + 1.0f);
}
//--------------------------------------------------
float ofRandom(float x, float y) {
float high = 0;
float low = 0;
float randNum = 0;
// if there is no range, return the value
if (x == y) return x; // float == ?, wise? epsilon?
high = MAX(x,y);
low = MIN(x,y);
randNum = low + ((high-low) * rand()/(RAND_MAX + 1.0));
return randNum;
}
You have to write the body of the null constructor i.e. Ball(). In this you are supposed to initialise all of your variables to some value which you will decide.
Otherwise these ints will have either garbage value or the default value 0.
Also color is an object of class ofColor right? So in the null constructor, you are supposed to initialize the value of color as well by calling its constructor in the constructor initializer list, like :
Ball(): color() or a parameterized constructor depending on what you wrote.
these are somethings that can be possible wrong with your constructor but since you havent posted the code I cant say.
Another thing is that you have initialized the variable rad inside the class. It is always good to initialize all variables in constructors, never in the class.

Struct property that returns a struct of its own type

I'm trying to define a struct in C++ that has properties to return pre-defined values of it's own type.
Like many APIs have for Vectors and Colors like:
Vector.Zero; // Returns a vector with values 0, 0, 0
Color.White; // Returns a Color with values 1, 1, 1, 1 (on scale from 0 to 1)
Vector.Up; // Returns a vector with values 0, 1 , 0 (Y up)
Source: http://msdn.microsoft.com/en-us/library/system.drawing.color.aspx
(MSDN's page of their Color type)
I've been trying to search for hours but I can't for the heart of me even figure out what it's called.
//in h file
struct Vector {
int x,y,z;
static const Vector Zero;
};
// in cpp file
const Vector Vector::Zero = {0,0,0};
Like this?
You can mimic it with static members:
struct Color {
float r, g, b;
Foo(float v_r, float v_g, float v_b):
r(v_r), g(v_g), b(v_b){};
static const Color White;
};
const Color Color::White(1.0f, 1.0f, 1.0f);
// In your own code
Color theColor = Color::White;
This is a static property. Unfortunately, C++ does not have properties of any type. To implement this, you probably want either a static method or a static variable. I would recommend the former.
For the Vector example, you would want something like:
struct Vector {
int _x;
int _y;
int _z;
Vector(int x, int y, int z) {
_x = x;
_y = y;
_z = z;
}
static Vector Zero() {
return Vector(0,0,0);
}
}
You would then write Vector::Zero() to get the zero vector.

C++ data structures: converting from TNT Vector to GL vec3

I'm using a data structure not written by myself that returns a realVec. This is the declaration of realVec (in typedef.h):
typedef TNT::Vector<PCReal> realVec;
For the definition of TNT Vector please see: http://calicam.sourceforge.net/doxygen/tnt__vector_8h_source.html
Definition of PCReal:
typedef double PCReal;
I need to convert this realVec into the following vec3:
struct vec3 {
GLfloat x;
GLfloat y;
GLfloat z;
//
// --- Constructors and Destructors ---
//
vec3( GLfloat s = GLfloat(0.0) ) :
x(s), y(s), z(s) {}
vec3( GLfloat _x, GLfloat _y, GLfloat _z ) :
x(_x), y(_y), z(_z) {}
vec3( const vec3& v ) { x = v.x; y = v.y; z = v.z; }
vec3( const vec2& v, const float f ) { x = v.x; y = v.y; z = f; }
...
I'm very new to C++ so my confusion probably lies in using TNT::Vector's iterator and converting values returned by it. I'm thinking something like the below, so tell me if it makes sense. It seems to compile (no 'make' errors):
realVec normal = this->meshPoints.getNormalForVertex(i);
PCReal* iter = normal.begin();
vec3(*iter++, *iter++, *iter++);
I need this because I'm doing gl programming, and it's convenient for my shaders to take vec3's as input.
What you have might work, but you could improve it with some safety checks, and you don't really have to use iterators at all. It appears realVec provides operator[] like most other vector classes.
realVec normal = this->meshPoints.getNormalForVertex(i);
if (normal.size() >= 3)
{
vec3 x(normal[0], normal[1], normal[2]);
}

Connecting the C++ class with the LUA table

I am trying to connect my 3d engine to a lua (5.1) parser.
For example, I have a LUA class of a vec3 and I have a C++ class of a vec3. I want them to work with eachother.
This is (part) of my C++ class:
class vec3
{
public:
vec3() {}
vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
vec3 operator+(const vec3 &b)
{
return vec3(x + b.x, y + b.y, z + b.z);
}
float dot(const vec3 &b)
{
return x * b.x + y * b.y + z * b.z;
}
float x, y, z;
}
This is the (limited) lua version:
vec3 = {};
vec3.__index = vec3;
local mt = {}
mt.__call = function(class_tbl, ...)
local obj = {}
setmetatable(obj, vec3);
vec3.init(obj, ...);
return obj;
end
vec3.init = function(obj, x, y, z)
obj.x, obj.y, obj.z = x, y, z;
end
setmetatable(vec3, mt);
function vec3:__tostring()
return "(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")";
end
function vec3:__add(b)
return vec3(self.x + b.x, self.y + b.y, self.z + b.z);
end
function vec3:dot(b)
return self.x * b.x + self.y * b.y + self.z * b.z;
end
I think the question is quite obvious: I want to be able to use vec3's in my C++ code, for example to position nodes or other stuff and then I want to be able to make these available in LUA where the LUA-programmer can do math with the vec3's and send them back to C++. So I also want to be able to construct a vec3 in LUA and send it to C++ where it is understood as a vec3 class.
To achieve this, I think I need to construct the above LUA table in C instead of in LUA and I need to create a function "push" and "pop" to send them to LUA and retrieve them from LUA.
But all my trials fail.
Can anyone help me get this to work?
Dirk.
What you need to do is create a userdata on the Lua stack in C++ and use that as the object. You can fairly simply placement new into it and arrange the metatable from C++. Of course, this is hideously type-unsafe, amongst the other huge holes in the Lua system.
Why not try to use C++ packages like luabind or luabridge? In those you you can access any lua data from C++ and vice versa.