Default constructor with normal constructors for classes c++ - c++

I have been trying to understand the default constructor and i think i get it if it's the only constructor in the class. But what if i have more than one constructor defined in the class. What i am trying to do is to create a class "vector", which would store two dimensional vectors. I need one constructor to set the coordinates to the values given in the main function. I also need a default constructor, which when called, would set the coordinates to 0. I can't seem to figure out how to make both work in the same code
#include <iostream>
#include <string>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
class Vector {
double x_coord, y_coord;
public:
Vector(double x_coord=0, double y_coord=0); //default contructor???
Vector (double x, double y) //normal constructor
{
set_values (x,y);
}
void set_values(double new_x, double new_y) //function to set values for the vectors
{
x_coord=new_x;
y_coord=new_y;
}
double get_x()
{
return x_coord;
}
double get_y()
{
return y_coord;
}
};

I can imagine constructing objects of the class using the following:
Vector v1; // Construct with x = 0, y = 0
Vector v2(10); // Construct with x = 10, y = 0
Vector v3(10, 20); // Construct with x = 10, y = 20
You can accomplish all of that with just one constructor:
Vector(double x=0, double y=0) : x_coord(x), y_coord(y) {}
You don't need the second constructor.

The default constructor is the constructor invoked when you omit the parantheses when defining an instance of the class. Example:
Vector vec;
Here, the default constructor (Vector::Vector(double = 0, double = 0)) is executed.
You can remove the other constructor (Vector::Vector(double, double)) and use this definition for the default constructor:
Vector(double x_coord = 0, double y_coord = 0) {
set_values(x_coord, y_coord);
}
When you pass two arguments, this will be called automatically. Furthermore, an ambiguity is resolved: what if, with those two constructors, you passed two doubles? Which one of them should be called? The compiler would raise an error saying that the constructors are ambiguous.
Notes:
The set_values function does not seem helpful as it does not do any useful work. Use a member initializer list in the constructor instead to improve performance. Also, it is considered good style:
Vector(double x_coord = 0, double y_coord = 0): x_coord(x_coord), y_coord(y_coord) { }
Your extensive use of setters and getters looks... bad. It breaks encapsulation. Provide functions, which do not expose implementation details but perform useful operations such as move.

Nevermind, i figured it all out.
If anyone needs the answer:
You can have the default and other constructors defined in Class
class Vector {
double x_coord, y_coord;
public:
Vector(): x_coord(0), y_coord(0) {}; //default constructor
Vector (double x, double y) //normal constructor
{
set_values (x,y);
}
it's just the way you define your default constructor.

Related

Why is my struct constructor, which contains other structs, not working?

I'm trying to create a basic physics' simulation that calculates rectilinear movement.
When I tried to add a constructor to the Body struct, it showed the following error:
no matching function to call to 'Vector::Vector()'
Here's the code:
struct Point{
int x,y;
Point(int _x, int _y) : x(_x), y(_y)
{
}
};
struct Vector{
int value, direction;
Vector(int _value, int _direction) : value(_value), direction(_direction)
{
}
};
struct Body{
std::string ID;
int m;
Vector v, a;
Point pos;
Body(std::string _ID = "NONE", int _m = 0, Point _pos = Point(0, 0))
{
ID = _ID;
m = _m;
pos = _pos;
v = Vector(0, 0);
a = Vector(0, 0);
}
};
I don't have the slightest idea why this is happening.
I just figured out if I declare pos before v and a, the error replaces 'Vector' with 'Point'. Also, the constructor works perfectly without declaring any of those variables.
It's probably a very dumb overlook. Help.
Members are initialized before the constructor body is executed. Hence, the constructor body is the wrong place to initialize members. Use the member initialization list instead:
Body(std::string _ID = "NONE", int _m = 0, Point _pos = Point(0, 0))
: ID(_ID), m(_m), v(0,0), a(0,0), pos(_pos) {
}
In your code, because you did not specify an initializer for the members, they were default initialized before the constructor body runs. But Vector has no default constructor.
Note that members are initialized in the order they are listed in the class. Typically compilers warn when the order in the initializer list is different.
Both things, writing a default constructor for structs Vector and Point, and writing the Body constructor as a member initializer list, worked individually and together.
Thanks a lot.

C++ How to call a constructor parameter inside a class method

So I'm a total noob at C++, I decided to learn C++ and skipped directly to the Object-oriented programming. I'm coding a class called KineticEnergy that has a constructor with the parameters x and y which is assigned to the variables mass and velocity.
I have a class method called result() which calculates the Kinetic Energy using its formula. I want to call the parameters from my constructor within the formula but I have no idea what I'm exactly doing here (bad english, don't know how to explain). I am getting errors like "[Error] x was not declared in this scope". Here is the code I written:
#include <iostream>
#include <cmath>
using namespace std;
class KineticEnergy
{
public:
double mass;
double velocity;
KineticEnergy(double x, double y) {
mass = x;
velocity = y;
}
double result()
{
return (1/2) * (x * (pow(y, 2)));
} // What am I gonna do here for this to work?
};
int main()
{
double a = 12.1;
double b = 6.4;
KineticEnergy ke(a, b);
cout << ke.result();
return 0;
}
It is not necessary. your constructor parameters is saved in "mass" and "velocity" as class members.
double result()
{
return (1./2.) * (mass * (pow(velocity , 2.)));
}
Parameters of the parameterized constructor are not member variables. That's why you are storing param values in member variables inside of the parameterized constructor. So that, you should use member variables inside of the result() function.
try this
#include <iostream>
#include <cmath>
using namespace std;
class KineticEnergy
{
public:
double mass;
double velocity;
KineticEnergy(double x, double y) {
mass = x;
velocity = y;
}
double result()
{
return 0.5 * (mass * pow(velocity, 2));
}
};
int main()
{
double a = 12.1;
double b = 6.4;
double Result;
KineticEnergy ke(a, b);
Result = ke.result();
cout << Result;
}
x and y were declared in your constructor, therefore only known by your constructor. you cannot use them outside of it. however, mass and velocity are known variables of your class and can be used anywhere as long as they are public.
in your main you give mass and velocity of your ke object values, that's why you can call any method of your class that uses these variables after(again, as long as they're public)

Why do I get no instance of constructor matches argument list for code below in different files?

The client function
void main()
{
using namespace std;
double a = 4.0;
double b = 5;
COMPLEX::Complex cmplxone(4.0,5.0);
}
Complex Class
#ifndef Complex_HEADER_H_
#define Complex_HEADER_H_
#include <iostream>
namespace COMPLEX
{
class Complex
{
public:
enum MODE { RECT, POLAR };
private:
//object consists of four parts
double realpart; //user enters this either rectangular or polar
double imaginarypart; //user enters this either rectangular or polar
double angle;
double magnitude;
MODE mode;
//private functions
void setangle();
void setmag();
// Complex topolar() const;
// void torectangular();
//public functions
public:
Complex(); //Default constructor
Complex(double, double, MODE);
My Complex non-default constructor has 3 arguments.
When I define an object: cmplxone(4.0,5.0) it says no instance of constructor matches argument list for the first argument.
Your constructor only has 3 arguments, you have only specified 2.
You must either create a new constructor that takes 2 arguments or add a third argument into your method call.
--Edit--
You could make the third argument nullable, then if the argument is null use the default value else use the argument.
Another solution is to create a new constructor that takes the two doubles and inside that constructor create and set the default value.

2D Std::vector of a given class

I'm trying to use a vector to store x and y coordinates of certain data in my vector. I assumed the following would work but that is not the case. I have spent a lot of time searching hoping to get it to work but in vain. I appreciate any help whatsoever.
class A {
public:
A(size_t x, size_t y); //ctor
};
If I want to create a vector of type class A, so 2D, why is
std::vector<A> vec(10); not working?
void count(size_t x, size_t y) {
vec.at(x,y);
}
ERROR: error: no matching function for call to ‘std::vector<Board>::at(size_t, size_t&)
note: candidate expects 1 argument, 2 provided
Since class A's constructor has 2 variables, shouldn#t my vector of type A take 2 variables as well?
If not, what is the correct way of getting a 2d vector of class A such that I can call the .at()-function at x,y and get whatever is stored there?
This vector overload:
std::vector<A> vec(10);
makes 10 copies of type A by calling A's default constructor. Since you didn't provide a default constructor an error occurs. Provide the default constructor:
class A {
public:
A() = default;
};
int main() {
std::vector<A> v(10);
}
or use an appropriate constructor as a second parameter:
class A {
public:
A(size_t x, size_t y) {
// your code
}
};
int main() {
std::vector<A> v(10, A(1, 2));
}
That being said, don't confuse the vector of vectors:
std::vector<std::vector<T>> v;
with a simple constructor taking two parameters or a simple class having two data members.

Rectangle class with three constructors

I need to complete the Rectangle class. Write 3 constructors and a destructor to satisfy the main() below. Use constructor initializers for each constructor.
This is what is done:
class Rectangle
{
float* length;
float* width;
...
???
...
};
int main()
{
Rectangle r1;
Rectangle r2(4.5,2.3);
Rectangle r3(r2);
}
This is how I filled up the rectangle class:
class rectangle
{
private:
float* length;
float* width;
public:
rectangle(); //default constructor
rectangle(double w, double l); //constructor with parameters
rectangle(const rectangle&); //copy constructor
~rectangle(void);
double getWidth(void);
double getLength(void);
double perimeter(void) const;
double area(void) const;
};
...........
...........
...........
int main()
{
rectangle r1;
rectangle r2(4.5,2.3);
rectangle r3(r2);
//statements
}
I just want to know if am doing it right or wrong. Can anyone see if am missing smth or need to add to rectanglr class?!
I think that you are doing wrong because the definition
Rectangle r2(4.5,2.3);
does not have a corresponding constructor. Also take into account that the class in the assignment is named as Rectangle not rectangle.:)
I think that instead of length and width (why did you declare them as pointers?!) you should define four data members that will denote four points of the rectangle.
The declaration and the uses of the three constructors (default constructor, a custom constructor, and a copy constructor) look reasonable. Storing pointers to float does not look reasonable, however: you should just store floats (I would actually store doubles unless I have a reason to assume that there are a huge mount of rectangles). When storing floats, there is actually no need to have a copy constructor or a destructor. If you insist in storing float* and, thus, allocate memory, you shall also implement a copy assignment:
rectangle& rectangle::operator= (rectangle other) {
other.swap(*this);
return *this;
}
void rectangle::swap(rectangle& other) {
std::swap(this->length, other.length);
std::swap(this->width, other.width);
}