Related
I have a program with two classes, one for points and one for a rectangle. I need to make two objects of point class within my rectangle class and make them private. I can't figure out how to use the rectangle constructor to make the points with the points constructor, every time I do so I get the error "no default constructor exists for class "Point2d"". Even when I make a default constructor I still get this. I'm at a loss here.
#include <iostream>
#include <cmath>
using namespace std;
class point2D {
private:
int x = 0;
int y = 0;
public:
int getX() {
return x;
}
int getY() {
return y;
}
point2D(int ax, int ay) {
x = ax;
y = ay;
}
};
class rectangleType {
private:
point2D p0;
point2D p1;
public:
int getX0() {
return p0.getX();
}
int getY0() {
return p0.getY();
}
int getX1() {
return p1.getX();
}
int getY1() {
return p1.getY();
}
int getWidth() {
return abs(getX1() - getX0());
}
int getLength() {
return abs(getY1() - getY0());
}
int getPerimeter() {
return 2 * (getWidth() + getLength());
}
int getArea() {
return (getWidth() * getLength());
}
rectangleType(int ax0, int ay0, int ax1, int ay1) {
point2D p0(ax0, ay0);
point2D p1(ax1, ay1);
}
};
Members and base classes not otherwise specifically initialized in the base+member initialization list require provision of default construction. In it's simplest form, given this:
class S
{
public:
S(int) {}
};
this is not possible:
S s;
because the only ctor (default copy-ctor notwithstanding) defined requires an int argument and none was provided. This is, perhaps, intentional by whomever designed S . It may not make sense to have an S without that require argument.
Carrying this forward to your specific circumstance, you have a class, point2D, whose only defined course of construction (default copy-ctor notwithstanding) is this:
point2D(int ax, int ay)
Like S in our previous example, this means something like this:
point2D pt;
is not possible. But that is exactly what is happening here (along with several other problems)
rectangleType(int ax0, int ay0, int ax1, int ay1)
// here, before entering the function body below, p0 and p1
// must be successfully constructed *somehow*
{
point2D p0(ax0, ay0);
point2D p1(ax1, ay1);
}
Before the constructor body is entered, all base classes (of which you have none), and member variables (of which you have two: p0 and p1), must be constructed. Since you are not directly initializing your p0 and p1 members in a member initialization list, the compiler attempts to find default constructors (takes no arguments, or has sufficient default values for all arguments declared). It can't find one. By providing a non-default ctor as you have, you've declared "this is the way these should be constructed". The compiler is therefor saying it could not find a way to create these things successfully.
In your case, providing such a constructor, while possible, isn't necessarily the proper (and certainly not the only) solution. Yes, you can, but it turns out all that does is enhance later issues. For example that will allow this to compile:
rectangleType(int ax0, int ay0, int ax1, int ay1)
{
point2D p0(ax0, ay0);
point2D p1(ax1, ay1);
}
But now you have another problem. Your members p0 and p1 are not the ones you see above. All the code above does is declare two more id's with the same names as your members (thereby shadowing the latter into obscurity), construct them, discard them on function exit, and ultimately leave you with your two members default-initialized, but not with the provided arguments. Shortly thereafter, you scratch your head and wonder went wrong.
You could still provide that default-ctor for point2D (which you didn't want to before, but now feel somewhat 'forced' to), and then do this:
rectangleType(int ax0, int ay0, int ax1, int ay1)
{
p0 = point2D(ax0, ay0);
p1 = point2D(ax1, ay1);
}
But now we're just piling on the rubbish, and an anti-pattern is forming. Now we're default-constructing our p0 and p1 members using a ctor we didn't think we needed (and perhaps even purposely didn't want), and then were discarding those efforts by constructing two more point2D objects and using copy-assignment to reap them.
There is a better way
Member Initialization
The language provides a way of telling telling the compiler, "before entering my constructor body, first construct my base class (if any) and members like this" :
rectangleType(int ax0, int ay0, int ax1, int ay1)
: p0(ax0, ay0)
, p1(ax1, ay1)
{
}
The syntax may seem a bit odd, but apart from the leading colon you've seen the rest before. In fact, you were even using it before in your prior code, but in the wrong place, and for the wrong target variables. This syntax says "construct these members like this, then enter the class constructor function body."
Another Example
That isn't the only place you can (or should) use this feature of the language. For example, your point2D constructor looks like this:
point2D(int ax, int ay)
{
x = ax;
y = ay;
}
But now you know you can also do this:
point2D(int ax, int ay)
: x(ax)
, y(ay)
{
}
Granted, it won't matter much, and any compiler with a grain of sanity will generate similar/identical code in the above trivial usage of this feature, but it stresses a larger overall theme. Where possible, use member-initialization lists to construct members. It is generally more efficient, and in many cases massively so.
A Special Note About Ordering
I mention this only because it is often relevant, ,and can be the cause of some interesting behavior you were otherwise not expecting. When using a member initialization list, the order of construction of the members is not dictated by the order of the list; it is dictated by the order of the member declarations. An example to show what I mean.
In your class, points p0 and p1 are declared in that specific order, top-down. Using our newly discovered member-initialization syntax, what happens when we do this (note the order in the list of members):
rectangleType(int ax0, int ay0, int ax1, int ay1)
: p1(ax1, ay1)
, p0(ax0, ay0)
{
}
This looks like p1 will be constructed before p0. That is not the case. The order of declaration in the class is what matters. Since the class as this:
private:
point2D p0;
point2D p1;
That means p0 will be constructed first, then p1, regardless of the order in the member-initialization list. This can lead to some interesting behavior, especially when you're not expecting it. In your trivial case it wouldn't overall matter, but it is worth noting nonetheless.
Your error tells you that you have to create a default constructor for the points class, e.g.
point2D() {}
or if you want to move the x & y initialization to the constructor
point2D()
: x { 0 }, y { 0 } {}
It happens because you've created a specialized constructor that takes two parameters. If not for that, the compiler would have generated a default constructor for you. :)
As for the initialization in the rectangle class try this:
rectangleType(int ax0, int ay0, int ax1, int ay1)
: p { { ax0, ay0 } }, p1 { { ax1, ay1 } } {}
Also, to remove redundant assignment (thanks #user4581301) you could transform your current 2D(int ax, int ay) into this:
point2D(int ax, int ay)
: x { ax }, y { ay } {}
Further reading:
https://en.cppreference.com/w/cpp/language/constructor (again thank you #user4581301)
your constructor should look like this:
rectangleType(int ax0, int ay0, int ax1, int ay1)
: p0 {ax0, ay0},
p1 {ax1, ay1}
{}
this is a member initialization list, you initialize values p0 and p1 by passing the arguments to their respective construcotrs
I have the following parent child simple classes:
class BoundBases{
public:
virtual ~BoundBases() { }
};
// Rectangular Bounds for tree
class RectBounds : public BoundBases{
public:
// x, y center point
double x, y;
double w, h;
~RectBounds(){ }
// (_x, _y): center of rectangle bound. (_w, _h): width and height
RectBounds(double _x, double _y, double _w, double _h){
x = _x;
y = _y;
w = _w;
h = _h;
}
//... more functions
};
I also have the following function structure:
void MyClass::init( BoundBases &bounds, std::vector<int> &colsPartitioned)
{
printf("init - new\n");
BoundBases * bPtr = &bounds;
RectBounds * rBounds = dynamic_cast<RectBounds *>(bPtr);
if(rBounds){
// do something
}else{
throw runtime_error("dynamic cast fail");
}
}
The dynamic cast is failing even though I call the function with RectBounds type as an argument. What is the reason?
FIXED:
The function calling init passed BoundBases by value, as follows:
MyClass2::MyClass2( BoundBases boundBases, std::vector<int> colsPartitioned) { // creates new table
// set up partition
partScheme_ -> setColsPartitioned(colsPartitioned);
partScheme_ -> setBoundBases(boundBases);
partScheme_ -> init(boundBases, colsPartitioned);
}
I changed the signature to pass by reference and it worked. (&boundBases). Can someone explain why is that? I am new to C/C++.
You need a reference here because dynamic_cast will only work if the real type of your variable is of type RectBounds like :
BoundBases* dummy = new Rectbound();
You can downcast here because the real type is Rectbound, so it will work.
If you pass it by value, it will create a copy of only the BoundBase part of your object, losing the information about your real type.
This problem is known as slicing
I'm not sure why you are surprised by that behavior. BoundBases passed by value is just a BoundBases. So dynamic_casting that to a child cannot make that a RectBounds. That's exactly what dynamic_cast is supposed to do.
If it worked differently: How would it be determining what e.g. x,y are if it's only given a BoundBases. This is not defined.
I have a class CS which is to represent the co-ordinate system in 3D i.e.(x, y, z)
class CS
{
private:
double x;
double y;
double z;
}
CS::CS()
{
x = NULL;//this causes x = 0//i want the address of x to be 0x000000 & not x = 0
y = NULL;
z = NULL:
}
I want that the user can create a CS (0, 0, 0).
In the constructor i want to initialise the address of x, y & z to NULL.
this is to differentiate between the user defined (0, 0, 0) & the default value.
I am creating the objects of CS dynamically, so there is no point in using the following code:
class CS
{
private:
double *x;
double *y;
double *z;
}
CS:CS()
{
x = new double;
x = NULL;
//same for y & z
}
Primarily, i want to manually assign 0x000000 address to any variable(int or double or char) without using pointers.
any suggestions?
You can't change the positions of x,y,and z to be NULL, since there positions will always be offsets from the CS object. They will always exist. It's not that CS has an x like you have a car, it's like CS has an x like you have a head. You can't not have a head. If they were integers, you would have to make them pointers (like you said you didn't want to do), because that would be the only way to tell uninitialized from initialized. However, doubles have a magic value that is rarely used:
CS:CS()
: x(std::numeric_limits<double>::quiet_NaN())
: y(std::numeric_limits<double>::quiet_NaN())
: z(std::numeric_limits<double>::quiet_NaN())
{ }
Users probably won't be setting x, y, and z to (NOT A NUMBER) intentially.
Primarily, i want to manually assign 0x000000 address to any variable(int or double or char) without using pointers. any suggestions?
That's not what you want. What you want is the ability to detect whether a variable has been set or not.
Others have suggested things like using a specific floating-point value to detect the uninitialized state, but I suggest employing Boost.Optional. Consider:
class CS
{
private:
boost::optional<double> x;
boost::optional<double> y;
boost::optional<double> z;
}
boost::optional either stores the type you give to the template parameter or it stores nothing. You can test the difference with a simple boolean test:
if(x)
{
//Has data
}
else
{
//Has not been initialized
}
The downside is that accessing the data is a bit more complex:
x = 5.0; //Initialize the value. x now has data.
y = 4.0 * x; //Fails. x is not a double; it is an optional<double>.
y = 4.0 * (*x); //Compiles, but only works at runtime if x has a value.
You have several options:
Use pointers.
Use a boolean flag alongside each variable indicating whether the variable has been set.
If the range of allowable values is limited, you could use a special value to stand for "not set". For double, a not-a-number is often a natural candidate. For int and char it's often more tricky to pick a good value.
None of these options is indisputably better than the other two as they involve different tradeoffs. Take your pick.
Why can't you simply do this:
class CS
{
public:
// Constructs a CS initialized to 0, 0, 0
CS() : x(0), y(0), z(0), is_initialized(false) {}
// User defined values
CS(double newX, double newY, double newZ) : x(newX), y(newY), z(newZ), is_initialized(true) {}
private:
double x;
double y;
double z;
// If you need to know that this was initialized a certain way, you could use this suggestion from the comments:
bool is_initialized;
}
If I understand correctly, you want to be able to tell the difference between an invalid, default constructed CS and a valid one with values (0.0, 0.0, 0.0). This is exactly what boost::optional http://www.boost.org/doc/libs/1_47_0/libs/optional/doc/html/index.html is for.
You can't really represent it in the same number of bits without having a sentinel. If 0 is a valid number, then you can't use it. If you try and foist null handling into a value type you will have fundamentally incorrect and unmaintainable code.
When handling nulls properly you would expect to see an interface like this:
struct foo {
virtual ~foo() {}
virtual bool getX(double &val) = 0;
virtual bool getY(double &val) = 0;
virtual bool getZ(double &val) = 0;
};
The implementation can have a flag that it checks before access.
void some_func(foo *f) {
double x, y, z;
if (f->getX(x) && f->getY(y) && f->getZ(z)) {
cout << x << ", " << y << ", " << z << endl;
} else {
throw std::logic_error("expected some values here");
}
}
You don't want to use an invalid value and not know it. Having to check the return values is tedious obviously, but it gives you the most control. You could also have helpers or overloads that would throw if they weren't valid.
struct bar {
double getX() {
if (!valid)
throw std::logic_error("bar is not valid");
return x;
}
bool valid;
double x, y, z;
}
For me, the difference between foo and bar is that low level code handling the data shouldn't enforce a policy of whether the data is there or not. At higher levels of abstraction you can and should have expectations of whether the data should valid when you go to use it. The both can exist in a system, but foo is necessary.
One way to get the semantics of what you want would be to have the datatype of the coordinates be a type that carries with it a value indicating whether it has been assigned. Something like this.
template<typename T>
class CoordinateValue {
public:
CoordinateValue() : uninitialized(true), val(0) {}
CoordinateValue(T x) : uninitialized(false), val(x) {}
void setVal(T x) {val = x; uninitialized= false}
// Trivial getters
private:
T val;
bool uninitialized;
};
I'd prefer something like this over cuter methods unless memory is really scarce for some reason.
If the coordinates are either all default or all set, then you can have a single flag rather than a coordinate datatype that includes the flag.
I want that the user can create a CS (0, 0, 0). In the constructor i
want to initialise the address of x, y & z to NULL. this is to
differentiate between the user defined (0, 0, 0) & the default value.
I am creating the objects of CS dynamically, so there is no point in
using the following code:
This is the problem. Firstly, default value? What default value? Why should there be a default value? That's wrong. And secondly, it's fundamentally impossible for you to change the address of any variable.
What you want cannot be done and even if it could, it would be a horrendously bad idea.
You can't change the address of a variable. And you can't assign pointer values (like NULL, or nullptr in C++) to a variable of a non-pointer type, such as double.
The following reduced code sample does not do anything useful but two subsequent assignments to a data member pointer. The first assignment works, the second one gives a compiler error. Presumably because its to a nested member.
Question would be: Is it really just not possible to let a member pointer point to a nested member or am I missing any fancy syntax there?
struct Color {
float Red;
float Green;
float Blue; };
struct Material {
float Brightness;
Color DiffuseColor; };
int main() {
float Material::* ParamToAnimate;
ParamToAnimate = &Material::Brightness; // Ok
ParamToAnimate = &Material::DiffuseColor.Red; // Error! *whimper*
return 0; }
ATM I am working around by using byte offsets and a lot of casts. But that is ugly, I would better like to use those member pointers.
Yes, I know that question surely arised before (like nearly any question). Yes, I searched beforehand but found no satisfying answer.
Thanks for your time.
AFAIK, this is not possible. A pointer-to-member can only be formed by an expression of type &qualified_id, which is not your case.
Vite Falcon's solution is probably the most appropriate.
I assume you are trying to get the pointer to the datamember Red. Since this is defined in the struct Color the type of the pointer is Color::*. Hence your code should be:
int main() {
float Color::* ParamToAnimate;
ParamToAnimate = &Color::Red;
return 0; }
To use it, you need to bind it to an instance of Color for example:
void f(Color* p, float Color::* pParam)
{
p->*pParam = 10.0;
}
int main() {
float Color::* ParamToAnimate;
ParamToAnimate = &Color::Red;
Material m;
f(&m.DiffuseColor, ParamToAnimate);
return 0;
}
EDIT: Is it not possible to make the animation function a template? For example:
template<class T>
void f(T* p, float T::* pParam)
{
p->*pParam = 10.0;
}
int main() {
Material m;
f(&m.DiffuseColor, &Color::Red);
f(&m, &Material::Brightness);
return 0;
}
Instead of a member pointer, you can use a functor that returns a float* when given an instance of Material; change the type of ParamToAnimate to something like:
std::function<float*(Material&)>
On the plus side, it's portable - but on the downside, it requires a significant amount of boilerplate code and has significant runtime overhead.
If this is performance critical, I'd be tempted to stick with the offset method.
Basically you're trying to get a pointer to a float variable that you can animate. Why not use float*. The issue you're having there is that Brightness is a member of Material, however, Red is a member of Color and not Material, to the compiler. Using float* should solve your problem.
It's not possible. But there is a workaround very close to what you want to achieve. It involves putting the nested member into an union alongside with a "layout-compatible" anonymous struct. The downside is a bit bloated interface and the need of keeping definitions of sibling structs in sync.
struct Color {
float Red;
float Green;
float Blue; };
struct Material {
float Brightness;
union {
struct { // "Layout-compatible" with 'Color' (see citation below)
float DiffuseColorRed;
float DiffuseColorGreen;
float DiffuseColorBlue; };
Color DiffuseColor; }; };
int main() {
Material M;
float Material::* ParamToAnimate;
ParamToAnimate = &Material::DiffuseColorRed;
std::cin >> M.*ParamToAnimate;
std::cout << M.DiffuseColor.Red << std::endl;
return 0; }
ISO IEC 14882-2003 (c++03):
§3.9
11
If two types T1 and T2 are the same type, then T1 and T2 are
layout-compatible types. [Note: Layout-compatible enumerations are
described in 7.2. Layout-compatible POD-structs and POD-unions are
described in 9.2. ]
§9.2
16
If a POD-union contains two or more POD-structs that share a common
initial sequence, and if the POD-union object currently contains one
of these POD-structs, it is permitted to inspect the common initial
part of any of them. Two POD-structs share a common initial sequence
if corresponding members have layout-compatible types (and, for
bit-fields, the same widths) for a sequence of one or more initial
members.
Multiple nesting is possible too:
struct Color {
float Red;
float Green;
float Blue; };
struct Material {
float Brightness;
Color DiffuseColor; };
struct Wall {
union {
struct {
float SurfaceBrightness;
struct {
float SurfaceDiffuseColorRed;
float SurfaceDiffuseColorGreen;
float SurfaceDiffuseColorBlue; }; };
Material Surface; }; };
int main() {
Wall W;
float Wall::* ParamToAnimate;
ParamToAnimate = &Wall::SurfaceDiffuseColorRed;
std::cin >> W.*ParamToAnimate;
std::cout << W.Surface.DiffuseColor.Red << std::endl;
return 0; }
§9.2
14
Two POD-struct (clause 9) types are layout-compatible if they have the
same number of nonstatic data members, and corresponding nonstatic
data members (in order) have layout-compatible types (3.9).
How about inheritance instead of composition?
struct Color {
float Red;
float Green;
float Blue; };
struct DiffuseColor : public Color {
};
struct Material : public DiffuseColor {
float Brightness; };
int main() {
float Material::* ParamToAnimate;
ParamToAnimate = &Material::Brightness; // Ok
ParamToAnimate = &Material::DiffuseColor::Red; // Ok! *whew*
return 0; }
You could simply refactor such that you don't have the nested structure at all. Add a setter than unpacks the color into its component parts so that existing code need not change much, and go from there.
You could also take an optional second pointer that digs into the nested type. A single test to see if you need the second parameter may prove good enough compared to your current method, and would be more easily extended should additional fields turn up later.
Take that a step further, and you have a base MaterialPointer class with a virtual Dereference method. The case class can handle simple members, with derived classes handling nested members with whatever additional information they need to find them. A factory can then produce MaterialMember* objects of the appropriate type. Of course, now you're stuck with heap allocations, so this is likely a little too far to be practical.
Since at some point you need a pointer to the actual data, this may or may not work for you:
float Material::* ParamToAnimate;
ParamToAnimate = &Material::Brightness; // Ok
float Color::* Param2;
Param2 = &Color::Red;
Material mat;
mat.Brightness = 1.23f;
mat.DiffuseColor.Blue = 1.0f;
mat.DiffuseColor.Green = 2.0f;
mat.DiffuseColor.Red = 3.0f;
float f = mat.DiffuseColor.*Param2;
Is there a better way to initialise C structures in C++ code?
I can use initialiser lists at the variable declaration point; however, this isn't that useful if all arguments are not known at compile time, or if I'm not declaring a local/global instance, eg:
Legacy C code which declares the struct, and also has API's using it
typedef struct
{
int x, y, z;
} MyStruct;
C++ code using the C library
void doSomething(std::vector<MyStruct> &items)
{
items.push_back(MyStruct(5,rand()%100,items.size()));//doesn't work because there is no such constructor
items.push_back({5,rand()%100,items.size()});//not allowed either
//works, but much more to write...
MyStruct v;
v.x = 5;
v.y = rand()%100;
v.z = items.size();
items.push_back(v);
}
Creating local instances and then setting each member one at a time (myStruct.x = 5; etc) is a real pain, and somewhat hard to read when trying to add say 20 different items to the container...
If you can't add a constructor (which is the best solution in C++03 but you probably have compatibility constraint with C), you can write a function with the same effect:
MyStruct makeAMyStruct(int x, int y, int z)
{
MyStruct result = { x, y, z };
return result;
}
items.push_back(makeAMyStruct(5,rand()%100,items.size()));
Edit: I'd have checked now that C++0X offers something for this precise problem:
items.push_back(MyStruct{5,rand()%100,items.size()});
which is available in g++ 4.4.
You're looking for C99 compound literals. Example code:
struct foo *foo = malloc(sizeof *foo);
*foo = (struct foo){ bar, baz };
How about:
MyStruct v = {5, rand()%100, items.size()};
items.push_back(v);
Create a function to initialize it, similar to what a C++ constructor would do.
Not clear what you are asking. In C++, the obvious solution is to give the struct a constructor:
struct MyStruct {
int x, y, z;
MyStruct( int ax, int ay, int az ) : x( ax ), y( ay ), z( az ) {}
};
Another option is to derive from the struct and add a constructor there.
struct MyDerivedStruct : public MyStruct
{
MyDerivedStruct(int xi, int yi, int zi)
{
x = xi;
y = yi;
z = zi;
}
}
Then you can use this derived type in your own code and pass it to the C library when necessary. The language should take care of implicitly converting to MyStruct when appropriate.
As a bonus, you could also add other useful member functions, perhaps even wrapping many of the legacy C functions that use this type.