I get the error message Call to implicitly-deleted default constructor of 'std::array' when I try to compile my C++ project.
Header file cubic_patch.hpp
#include <array>
class Point3D{
public:
Point3D(float, float, float);
private:
float x,y,z;
};
class CubicPatch{
public:
CubicPatch(std::array<Point3D, 16>);
std::array<CubicPatch*, 2> LeftRightSplit(float, float);
std::array<Point3D, 16> cp;
CubicPatch *up, *right, *down, *left;
};
Source file cubic_patch.cpp
#include "cubic_patch.hpp"
Point3D::Point3D(float x, float y, float z){
x = x;
y = y;
z = z;
}
CubicPatch::CubicPatch(std::array<Point3D, 16> CP){// **Call to implicitly-deleted default constructor of 'std::arraw<Point3D, 16>'**
cp = CP;
}
std::array<CubicPatch*, 2> CubicPatch::LeftRightSplit(float tLeft, float tRight){
std::array<CubicPatch*, 2> newpatch;
/* No code for now. */
return newpatch;
}
Could someone tell me what is the problem here, please ? I found similar topics but not really the same and I didn't understand the explanations given.
Thanks.
Two things. Class members are initialized before the body of the constructor, and a default constructor is a constructor with no arguments.
Because you didn't tell the compiler how to initialize cp, it tries to call the default constructor for std::array<Point3D, 16>, and there is none, because there is no default constructor for Point3D.
CubicPatch::CubicPatch(std::array<Point3D, 16> CP)
// cp is attempted to be initialized here!
{
cp = CP;
}
You can get around this by simply providing an initializer list with your Constructor definition.
CubicPatch::CubicPatch(std::array<Point3D, 16> CP)
: cp(CP)
{}
Also, you might want to have a look at this code.
Point3D::Point3D(float x, float y, float z){
x = x;
y = y;
z = z;
}
x = x, y = y, z = z doesn't make sense. You're assigning a variable to itself. this->x = x is one option to fix that, but a more c++ style option is to use initializer lists as with cp. They allow you to use the same name for a parameter and a member without the use of this->x = x
Point3D::Point3D(float x, float y, float z)
: x(x)
, y(y)
, z(z)
{}
Related
So i created the class Point and want to use it as the parameter of the constructor in the class Circle , but the error : There is no default constructor for class "Point" shows up and I dont know how to fix it. The code is represented below this text:
class Point {
private:
int x, y;
public:
Point(int X, int Y) {
x = X;
y = Y;
}
};
class Circle {
private:
int radius;
Point centre;
public:
Circle(Point q, int r) {
centre = q;
radius = r;
}
};
int main() {
Point obj = Point(3, 4);
Circle obj = Circle(obj, 3);
}
The first problem is that when the constructor Circle::Cirlce(Point, int) is implicitly called by the compiler, before executing the body of that ctor, the data members centre and radius are default initialized. But since you've provided a user-defined ctor Point::Point(int, int) for class Point, the compiler will not synthesize the default ctor Point::Point(). Thus, the data member centre cannot be default initialized.
To solve this you can use constructor initializer list as shown below. The constructor initializer list shown below, copy initialize the data member centre instead of default initializing it.
class Point {
private:
int x, y;
public:
Point(int X, int Y) {
x = X;
y = Y;
}
};
class Circle {
private:
int radius;
Point centre;
public:
//--------------------------vvvvvvvvvvvvvvvvvvvv--->constructor initializer list used here
Circle(Point q, int r): radius(r), centre(q)
{
}
};
int main() {
Point obj = Point(3, 4);
Circle circleObj(obj,4);
}
Demo
Additionally, you had 2 objects with the same name obj inside main.
I have a simple math vector struct
struct vec3d {
float x;
float y;
float z;
float w;
public:
vec3d(float a, float b, float c) { a = x; b = y; c = z; w = 1; }
vec3d() { x = 0; y = 0; z = 0; w = 1; }
};
With the following operation in a function (I am not using operator overloading)
vec3d vsubvector(vec3d& v1, vec3d& v2)
{
return vec3d(v1.x - v2.x, v1.y - v2.y,v1.z - v2.z);
}
I am using it inside the main function within a loop block like this
{
...
vec3d normal, line1, line2;
line1 = vsubvector(p[1], p[0]);
line2 = vsubvector(p[2], p[0]);
normal = vcrossproduct(line1, line2);
normal = vnormalise(normal);
...
}
Here p is an array of three vectors
Now while debugging, when I enter the block where the local variable is defined, line1.x, line1.y and line1.z are assigned a big signed float value (-107374176.0f) and they do not change after the subtract function is returned into them.
What is the reason that vsubvector function is not working?
vec3d(float a, float b, float c) { a = x; b = y; c = z; w = 1; }
Is assigning to the constructor arguments from the uninitialised member variables. Obviously wrong. You'd want to reverse the order of assignment.
Additionally, you should use the constructors initialization list to initialize members rather than the constructor body. Do this:
vec3d(float a, float b, float c) : x(a), y(b), z(c), w(1) { }
For basic types like ints or floats it makes little difference, but for user defined types it can make a big difference. It is wasteful to first let the constructor default initialize members and then subsequently assign to them in the constructor body. Also, for some types, doing so is not even possible, not all types support assignment so initialization is the only option.
Additionally, the default constructor vec3d() can delegate to the other constructor:
vec3d() : vec3d(0.f, 0.f, 0.f) {}
I cannot seem to find why I am getting the build error
expected primary-expression before "float"
In this implementation...
using namespace std;
class Point{
public:
Point(float X = 0.0, float Y = 0.0);
void set(float X, float Y);
void setX(float X);
void setY(float Y);
void get(float * P_x, float * P_y);
float getX();
float getY();
float * pX();
float * pY();
SDL_Point returnSDL();
private:
float x;
float y;
};
class Vector : public Point{
public:
Vector(float X = 0.0, float Y = 0.0);
};
///The errors occur in this constructor...
Vector::Vector(float X, float Y) : Point(float X, float Y){
}
Im still learning about the finer points of classes and would appreciate any help. I know it has something to do with the inheritance because when Vector doesn't inherit Point the program builds normally. As far as i can tell this is the correct syntax and implementation of inheritance. Web help i have found cannot answer so far.
///The errors occur in this constructor...
Vector::Vector(float X, float Y) : Point(float X, float Y){
}
There are two similar constructions in this fragment of code:
Vector::Vector(float X, float Y) and : Point(float X, float Y):
the first one (Vector::Vector(float X, float Y)) is the declaration of the constructor of class Vector;
the other one (: Point(float X, float Y)) is a function call; a call of the constructor of class Point; notice the colon (:) that introduce the list of member initializers.
Now, if you see the difference between the two (function/method declaration or definition vs. function/method call) you can find the error yourself: the compiler expects expressions and not types in the arguments list of the call to the Point::Point() constructor.
// Look, ma! No errors!
Vector::Vector(float X, float Y) : Point(X, Y) {
}
For more information take a look at the documentation page about constructors and member initializer lists.
You are confusing declaring a function and using a function. When you declare a function you need to tell the compiler what the types of the parameters are.
Vector::Vector(float X, float Y)
Now in the member initialization part you have
: Point(float X, float Y)
Here you are adding types to the function call which is not what you want to do. When you call a function you just pass the values/variables to it.
: Point( X, Y)
^ ^ no type here as we just pass X and Y to the Point constructor.
Been banging my head against this all day with many trips to google.
I have a master object that needs to create several other objects in its constructor the main object gets variables in its constructor that are passed on to the objects it creates.
class WorldManager{
public:
WorldManager(int x, int y, int z){
//do stuff
}
}
class GameManager{
public:
WorldManager world;
GameManager(int x, int y, int z){
world(x,y,z);
}
}
I get error
error: no matching function for call to `GAMEMANAGER::GraphicsManager(HWND__*&, int&, int&)'
it works untill I ask for args in the constructors of the world class
I think that you want:
class GameManager{
public:
WorldManager world;
GameManager(int x, int y, int z) : world(x, y, z) { }
};
The weird colon thing is called an initialization list, and it does construction of member objects and parent classes and a bunch of other things.
If you have more than one object that you want to construct, add them to the list:
class GameManager{
public:
WorldManager world1, world2;
GameManager(int x, int y, int z) : world1(x, y, z), world2(x, y, z) { }
};
I have Struct like these
typedef struct sample
{
double x,
double y,
double z
}s1;
s1 s;
will the content in s variable initialized or not?
What will be the values of x,y,z?
thanks
x, y and z won't be initialized if s is defined in a function scope. They would be containing some unspecified values. At file scope the data members would be initialized to their default values.
In C++ however you can have a constructor initializer list to initialize the data members
For example
struct ABC
{
int x;
int y;
ABC(): x(1),y(2){}
};
ABC s; // x and y initialized to 1 and 2 respectively
In C++ you also have default initialization and value initialization to initialize data members.
In the code you presented, the fields will be uninitialized. You can add a constructor (if you need/can), or in case you need the POD-ness (some part of your code depends on some of those properties) and you cannot add a constructor, you can still value-initialize the struct (i.e. set each member to 0) at the place of use:
struct sample // typedef not required
{
double x,
double y,
double z
};
sample s = sample(); // will set all members to 0.0
Now, if you want to initialize different members with some particular values, because it is an aggregate you can use aggregate initialization:
sample s = { 1.0, 3.0 };
That will set x to 1.0, y to 3.0. Since there is no value for z, the compiler will set it to 0.0. Note that this means that sample s = {}; is equivalent to sample s = sample();
If it is C++, you could make constructor.
struct s1
{
s1( const double x = 0.0, const double y = 0.0, const double z = 0.0 )
: x(x), y(y), z(z)
{
};
double x;
double y;
double z;
};
s1 s;
Built-in types like double and int are initialised if the variable is static or at namespace/file scope, otherwise - for efficiency reasons - they're not initialised unless a constructor indicates that's useful.
Note: this answer addresses the "s1 s;" situation you describe. It is possible to provide an explicit initialisation when defining the variable, but that's another case.
To add a constructor so:
struct X
{
X() : x_(0), y_(0), z_(0) { }
double x, y, z;
};