I have a problem with my derived class called Square. A square's sides are always equal, so I want there a way for me to send it to the parent class (Rectangle) in a way that it doesn't call the default constructor, but provides a constructor with 1 parameter. However, it finds a problem that it can't tell the difference between the default constructor and the constructor for when the length and width are the same. Is there any way I can explicitly make sure that the Square constructor doesn't call the default constructor instead of the preferred?
class Rectangle : public Quadrilateral
{
private:
int length{};
int width{};
public:
Rectangle(int len = 1, int wid = 1) : length{ len }, width{ wid }
{
}
Rectangle(int s) : length{ s }, width{ s }
{
}
const int area() { return length * width; }
};
class Square : public Rectangle
{
private:
int side{};
public:
Square(int s = 1) : Rectangle{ s } // Call Rectangle w/ one parameter
{
}
int getSide() const { return side; }
int perimeter() { return 4 * side; }
};```
The problem is that there are two ways to get a Rectangle when you have an int. One is to call the first constructor with wid as the default 1, and the other is to call the single argument constructor.
I would argue that this is the result of using default values for parameters. If you need default values, I'd say just make another overload of the function that accepts one fewer parameter and forwards the call to the other function, passing the default value. This way you'll quickly notice that you have two overloads with the exact same signature (taking one int).
You either:
Make up your mind and decide what Rectangle(int) means (either it's just length with default width, or it's both length and width)
Call the Rectangle constructor with two arguments in the first place in Square(int)
Related
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.
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.
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);
}
I wrote a program for binary heap given below
#include<iostream>
using namespace std;
class BinaryHeap
{
private:
int currentSize; // Number of elements in heap
int array[]; // The heap array
void buildHeap( );
void percolateDown( int hole );
public:
bool isEmpty( ) const;
bool isFull( ) const;
int findmini( ) const;
void insert( int x );
void deleteMin( );
void deleteMin( int minItem );
void makeEmpty( );
public :
BinaryHeap( int capacity )
{
array[capacity + 1];
currentSize = 0;
}
};
int main()
{
int resp, ch, choice;
int n, i;
Binaryheap b;
cout << "enter the size of heap" << endl;
cin >> n;
BinaryHeap(n);
return (0);
}
while compiling it gives error as - 'binaryheap' was not declared in this scope at the line where i wrote the code BinaryHeap b;
What is the cause of the eroor and how it could be resolved?
C++ is case sensitive. Change Binaryheap b; to BinaryHeap b;.
Besides, your constructor takes one parameter, so you need to construct your objects using a constructor call with one parameter. See Huytard's answer for an example.
You defined the constructor with an int so that's what you probably intend to use.
BinaryHeap b(20);
You have defined only a parameterised constructor. When you do this, the default constructor is not made available by default. This is to avoid cases which can lead to the object not being initialised properly.
Consider,
class Dog
{
int height;
public:
Dog(int x)
{
height = x;
}
};
In this case, you should have a height for every Dog. If a default constructor is provided by default you can do Dog d i.e A Dog with no height (Not Good!)
Either define a default constructor for BinaryHeap or call it only when you pass an int
like in BinaryHeap(n);
You seem to call Binaryheap b. h instead of H
You need to make sure that you use the same case declaration where ever you call it.
Your current error is simply a case sensitivity typo,
"Binaryheap b;" isn't declared because.. it actually isn't.
Your class is named "BinaryHeap"(capital h!), so the object in question needs to be named with a capital h as well.
This gives you another error.
When you defined your constructor for BinaryHeap, you immediately lost the use of your default constructor. This explains why "b" remains underlined; it's declaration is incomplete!
You can fix this in two ways:
Make yourself a parameter-less constructor for BinaryHeap.
Complete "b"'s declaration.
Hope this helps! Best of luck!
Shape.h
class Shape {
private:
string name;
public:
Shape(name);
string getName();
void setName(string);
};
Triangle.h
class Triangle: public Shape {
private:
int x;
int y;
public:
Triangle(name,int[3],int[3]);
int getX();
int getY();
void setX(int);
void setY(int);
};
Triangle.cpp
Triangle::Triangle(string name,int _x[],int_y[]):Shape(name) {
x[] = _x[];
y[] = _y[];
}
int Square::getX() {
return x
}
int Square::getY() {
return y;
}
void Square::setX(int _x) {
x = _x;
}
void Square::setY(int _y) {
y = _y;
}
i need to create triangle that takes in name and 3 points of (x,y). when i try to create an array of triangle on the main Triangle Tri[50]; i got the following errors
Triangle::Triangle(std::string,int*,int*)
candidates expects 3 arguments, 0 provided
Triangle::Triangle(const Triangle&)
candidates expects 1 argument, 0 provided
can pls help me check what is wrong with my constructor?? is it because i am creating an array of objects that store arrays of x and y? so i need to use references and pointers for it?
When you create
Triangle Tri[50];
it will try to call the default constructor to initialize those elements in your Tri array, however, you did not provide such a default constructor and you did not call the constructor with 3 parameters, therefore, compiler complains.
Meanwhile, you seems to try to directly initialize one array with another inside the constructor of Triangle:
Triangle::Triangle(string name,int _x[],int_y[]):Shape(name) {
x[] = _x[];//^^I don't understand how this will work in practice.
y[] = _y[];
}
There is no direct assignment on arrays in C++, though C++ std::array (since C++11) has overloaded operator=, but this is not true for regular array.