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;
};
Related
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) {}
Is there an equivalent to Delphi's absolute in C++? I want to do the following:
// Structure A
struct A
{
double X;
double Y;
double Z;
}
// Structure B
struct B : A
{
double U absolute X;
double V absolute Y;
double W absolute Z;
}
I can use double & U = X in structure B but this will generate an additional pointer and change the size of the structure. Union is - I think - also not a solution, because structure B inherits structure A.
What I really want is to have access to the same memory by accessing for example X or U.
I like the idea of user2079303's answers, but want to inverse it.
Note - the question is named wrong and is violating "what is your real goal" or "show me your Z" rule. We do not need to mimic absolute keyword - it is total nonsense! we want to make pseudonyms for the record properties and use them interchangeably.
What I really want is to have access to the same memory by accessing for example X or U.
The quoted line is the ONLY line in the question that talks about the problem essence - making full pseudonyms.
So, let's start where user2079303 stopped and use the fact that C's unions do not have to be named, like it was used in https://stackoverflow.com/a/13624921/976391
So we just inverse the scopes.
/*union*/ struct coordinates {
/*struct*/ union {
double X;
double U;
};
/*struct*/ union {
double Y;
double V;
};
/*struct*/ union {
double Z;
double W;
};
};
Short version: There is no equivalent of the described language feature.
Long version C++:
There isn't an equivalent in C++. The member reference that you suggest gives you the same syntax, but indeed increases the size of the object.
Another close alternative is a member function, that returns a reference. That has no overhead (assuming inline expansion). A function call has different syntax than referencing a member though. But perhaps having identical syntax with member access is not important so this is what I suggest.
Long version C:
There is no inheritance in C at all, so there is nothing like the described "absolute" in it either.
we have several kinds of coordinates. Some of them are named x, y, z others (in another system) are named u, v, w.
Given this context, I would suggest a union (EDIT: It's better to swap the union and struct relation, see https://stackoverflow.com/a/41148089/2079303):
union coordinates {
struct {
float x, y, z;
} xyz;
struct {
float u, v, w;
} uvw;
};
If you want to interchangeably use XYZ and UVW, you can let each convert to the other.
// forward declare
struct B;
struct A
{
double X;
double Y;
double Z;
operator B() const;
}
struct B
{
double U;
double V;
double W;
operator A() const;
}
A::operator B() const { B b; b.U = X; b.V = Y; b.W = Z; return b; }
B::operator A() const { A a; a.X = U; a.Y = V; a.Z = W; return a; }
As of C++11, there seem to be three viable ways to define simple structs. (I know that in C++14 option A and B can be combined, but my question relates to C++11).
// non-static member initialization
struct PointA
{
double x = 0.0;
double y = 0.0;
};
PointA pA1;
PointA pA2; pA2.x = 2.0; pA2.y = -1.0; // can this be made more elegantly ?
// aggregate initialization
struct PointB
{
double x;
double y;
};
PointB pB1 = { 0.0, 0.0 }; // or does it suffice to write PointB pB1; here?
PointB pB2 = { 2.0, -1.0 };
// constructor
struct PointC
{
double x;
double y;
PointC(double initX = 0.0, double initY = 0.0) : x(initX), y(initY) { }
};
PointC pC1;
PointC pC2( 2.0, -1.0 );
What are the advantages/disadvantages of using each of them ? And which should be preferred in which circumstances in C++11 ? (and would this change if C++14 combined member and aggregate initialization was available ?)
In c++14, I prefer
struct PointA
{
double x = 0.0;
double y = 0.0;
};
which allows
PointA pA1; // {0., 0.}
PointA pA2 = { 2.0, -1.0 };
but also
PointA pA3 = { 2.0 }; // {2., 0.}
which may be undesirable.
In c++11 (or if you want to forbid some constructors):
struct PointD
{
PointD() : PointD(0, 0) {}
PointD(double x, double y) : x(x), y(y) {}
double x;
double y;
};
A constructor's job is to establish a user defined class invariant.
If there is no user defined class invariant then a constructor's job is just to make sure that all data members have valid values, i.e. are not indeterminate (such values can lead to Undefined Behavior when used).
When the only class invariant is that “data members have valid values”, the secondary job, then a constructor is only needed as a way to make the class idiot-proof, so that a novice cannot use it to declare an uninitialized variable. But this has the cost of making the class non-POD. These concerns must be balanced, but it's worth keeping in mind that you can always define a POD class plus a derived class that has constructor.
Regarding the first code example,
struct Point
{
double x = 0.0;
double y = 0.0;
};
Point a1;
Point a2; a2.x = 2.0; a2.y = -1.0; // can this be made more elegantly ?
Due to the data member initializers this class effectively has a constructor like:
Point::Point()
: x( 0.0 ), y( 0.0 )
{}
And this prevents compilation with Visual C++ 2015 of a declaration like
Point point = { 5.0, 6.0 };
The declaration is accepted by MinGW g++ 5.1.0. I don't know the formal of this. But as a matter of practical programming, the different compiler behaviors means that currently there is no more elegant way to do the commented declaration of a2 in your example.
Regarding the second code example,
// aggregate initialization
struct Point
{
double x;
double y;
};
Point b1 = { 0.0, 0.0 }; // or does it suffice to write PointB pB1; here?
Point b2 = { 2.0, -1.0 };
Whether it suffices to write just Point b1; depends:
If this is a namespace scope declaration then b1 is zero-initialized first of all, so there it's OK.
If this is a local declaration then there is no automatic zero-initialization, and so omitting the explicit initialization would give you indeterminate values, leading to UB.
However, you can reduce the declaration to just
Point b1 = {};
or
Point b1{};
depending on your general conventions.
You can rely on default constructor.
You can simplify any constructor(s) you define.
No it doesn't suffice to write PointB pB1. But you can just put
PointB pB1{{},{}};
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)
{}
I'm constructing a class where I have three member variables that I want to always be the same value NO MATTER WHAT.
I have
class foo{
public:
double var_1, var_2, var_3;
double x=1, y=2, z=3;
[functions go here]
};
that gave me an error since I can't initialize a variable like that. But I want x, y and z to always be 1, 2 and 3 respectively. I tried defining them outside the class but that doesn't work since I want them to be member variables of the class.
How do I do this?
make these values static for the class, this way all object will inherit these same values.
static const int x = 1;
static const int y = 2;
static const int z = 3;
through technically, this does not define the variable. If a static data member is of const integral or const enumeration type, you may specify a constant initializer in the static data member's declaration. This constant initializer must be an integral constant expression. Note that the constant initializer is not a definition. You still need to define the static member in an enclosing namespace.
#include "foo.h"
#include <//libs....>
int foo::x;
int foo::y;
int foo::z;
//class functions down below
You can also use an initializer list in the constructor to set these fields' initial values, just as with any other member:
class foo {
public:
const double x;
const double y;
const double z;
foo() : x(1), y(2), z(3) {
}
};
You don't have to make them static. You could declare them like this:
class foo{
public:
double var_1, var_2, var_3;
const double x=1.0;
const double y=2.0;
const double z=3.0;
[functions go here]
};
Though if they are integer values then declaring them as ints would be better.