I am writing a simple program to calculate the area, the error that i am getting is :
no matching function for call to 'myclass::myclass()'
I am unable to understand the reason for this error and how to resolve it.
#include <iostream>
using namespace std;
class myclass{
int length;
int breadth;
public:
myclass(int x, int y);
int area(int x, int y);
};
myclass::myclass(int x,int y ){
length=x;
breadth=y;
}
int myclass::area(int x, int y){
return x*y;
}
int main()
{
myclass a;
a.area(3,4);
}
In this statement
myclass a;
there shall be called the default constructor of the class but you did not define the default constructor.
Also member function area has no a greate sense because it does not calculate the area of an object of the class.
The valid code could look as
#include <iostream>
class myclass
{
private:
int length;
int breadth;
public:
myclass(int x, int y);
int area() const;
};
myclass::myclass(int x,int y ) : length( x ), breadth( y )
{
}
int myclass::area() const
{
return length * breadth;
}
int main()
{
myclass a(3,4);
std::cout << "area = " << a.area() << std::endl;
}
Also you could declare the constructor the following way
myclass( int x = 0, int y = 0 );
In this case it would be a default constructor.
You have defined a constructor, which means the compiler is required not to define any constructors for you, including the default one. If you're using C++11, you can add this:
myclass() = default;
If not:
myclass() : length(0), breadth(0) {}
To the class declaration/body.
The error is because there is no default constructor and you are trying to call it. Since you have written your own constructor, you have overwritten the default constructor. One suggestion is to always write a default constructor or in your case, make sure you don't call default constructor.
Change the code in this way:
#include <iostream>
using namespace std;
class myclass{
int length;
int breadth;
public:
myclass(int x, int y);
int area(int x, int y);
};
myclass::myclass(int x,int y ){
length=x;
breadth=y;
}
int myclass::area(){
return length*breadth;
}
int main()
{
myclass a(3,4);
a.area();
}
You have defined a constructor for your class. This means that the compiler will not generate a default constructor, even though you're trying to call it inside main. There are two solutions:
Remove the custom constructor from your class:
myclass(int x, int y);
BUT, most likely you need that constructor, so simply instantiate the class using the parameters in the constructor you created, like this:
int main()
{
myclass a;
a.area(3,4);
}
EDIT:
My mind slipped a bit, there's a third solution. Use BOTH constructors. This would be the optimal solution if you think you will need to instantiate the class without any values assigned to the private elements:
public:
myclass();
myclass(int x, int y);
Related
I want to explicitly change the second parameter in a constructor of a struct, in the following scenario. Is it possible, if so, how?
struct foo{
int x;
int y;
foo(int a=4, int b=6){
x=a;
y=b;
}
};
int main(){
foo *f = new foo();
cout<<f->x<<" "<<f->y<<endl;
//4 6
foo *g = new foo(3,4);
cout<<g->x<<" "<<g->y<<endl;
//3 4
foo *h = new foo(3);
cout<<h->x<<" "<<h->y<<endl;
//3 6
//Can something like this be
//done in C++, if I want
//to change the value of the
//second variable only
foo *k = new foo(b = 13);
return 0;
}
Is it possible, if so, how?
It is not possible with constructor. In general, c++ does not support named keyword arguments to functions, and it is not possible to skip arguments even if they have a default, if you want to pass a non-default after it.
It will be possible without constructor using list initialisation syntax since C++20 using designated initialisers, if you use default member initialisers:
struct foo{
int x = 4;
int y = 6;
};
int main(){
foo f {.y = 4};
}
You can achieve something similar with tag dispatching; No need for future standard:
struct foo{
int x = 4;
int y = 6;
enum Xtag { Xinit };
enum Ytag { Yinit };
foo(int a, int b) : x(a), y(b) {}
foo(Xtag, int a) : x(a) {}
foo(Ytag, int b) : y(b) {}
};
int main(){
foo f(foo::Yinit, 4);
}
A solution using lambda that can be used without modifying an existing class. Following works with your definition of foo:
auto make_foo_x4 = [](int b) {
return foo(4, b);
};
foo f = make_foo_y(4);
The downside is that we have to explicitly repeat the default value of x, so this can break assumptions if the default is changed in class definition.
I have template function change that takes a function that takes int and returns an object of type A. So I thought I can use the constructor of A
class A {
int y;
public:
explicit A(int y) : y(2 * y) {
}
};
class B {
A x;
public:
B(int x) : x(x) {
}
template<typename F>
void change(int y, F func) {
x = func(y);
}
};
int main(void) {
B b(7);
b.change(88, A()); // << here
return 0;
}
But the compiler says no matching function for call to ‘A::A()’
How can I make it works?
You can't pass a constructor as a parameter like you are attempting. The C++ standard is very strict on not allowing the memory address of a constructor to be taken.
When you call change(88, A()), you are actually constructing a temp A object (which the compiler should not allow since A does not have a default constructor) and then you are passing that object to the parameter of change(). The compiler is correct to complain, since A does not define an operator()(int) to satisfy the call to func(y) when called in an A object.
To make this work, you need to create a separate function that constructs the A object, and then pass that function to change(), eg:
A createA(int y)
{
return A(y);
}
int main(void) {
B b(7);
b.change(88, createA);
return 0;
}
#include<iostream>
#include<conio.h>
using namespace std;
class one
{
int r;
public:
one(int a) : r(a) {}
void set(int a) { r = a; }
int area() { return r*r*3.14; }
};
class two
{
one x;
int hi;
public:
two(int r, int h)
{
hi=h;
x.set(r);
}
int v() { return x.area()*hi; }
};
int main()
{
_getch();
return 0;
}
the error is:no appropriate default constructer available.
would you mind helping me so that i can get rid of this error.
//.............................................................................
When you declare x in two, C++ basically tries to create an instance of one using a constructor without any parameters (default constructor), since "null objects" do not exist in C++.
one does not provide a default constructor, but it provides the constructor one(int a), so instead of one x;, use one x(0); or one x = one(0);
What's the proper way to set up the following constructor for SquareValue?
I'm getting the following Error:
"constructor for SquareValue must explicitly initialize the member "square" which does not have a default constructor"
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class Square {
public:
int X, Y;
Square(int x_val, int y_val) {
X = x_val;
Y = y_val;
}
};
class SquareValue {
public:
Square square;
int value;
SquareValue(Square current_square, int square_value) {
square = current_square;
value = square_value;
}
};
I had planned on passing the Square() constructor into the SquareValue constructor.
When you don't initialize an object using the list initialization syntax in the constructor, the default constructor is used:
SquareValue(Square current_square, int square_value) {
square = current_square;
value = square_value;
}
is equivalent to:
SquareValue(Square current_square, int square_value) : square() {
square = current_square;
value = square_value;
}
square() is a problem since Square does not have a default constructor.
Use:
SquareValue(Square current_square, int square_value) :
square(current_square), value(square_value) {}
That is not a duplicate. Please read carefully. There are two variables x (of type int and X) and one member is actually declared private, which is used in a constructor. It is about understanding the constructor process in this very specific case.
I am doing a C++ course and I understand the following example that was given. It is about constructors.
#include <iostream>
using namespace std;
class Element {
int value;
public:
Element(int val) {
value = val;
cout << "Element(" << val << ") constructed!" << endl;
}
int Get(void) {
return value;
}
void Put(int val) {
value = val;
}
};
class Collection {
Element el1, el2;
public:
Collection(void) : el2(2), el1(1) {
cout << "Collection constructed!" << endl;
}
int Get(int elno) {
return elno == 1 ? el1.Get() : el2.Get();
}
int Put(int elno, int val) {
if (elno == 1) el1.Put(val);
else el2.Put(val);
}
};
int main(void) {
Collection coll;
return 0;
}
Then they mentioned the following
...
We should also add that there is the following alternation for that
case: when the constructor is divided between the declaration and the
definition, the list of alternative constructors should be associated
with the definition, not the declaration.
It means that the following snippet is correct:
class X {
public:
X(int x) { };
};
class Y {
X x;
public:
Y(int x);
};
Y::Y(int x) : x(1) { };
Can someone explain? Is it really correct? And if yes, how to interpret that? Y has a one-parameter constructor, but no value is passed. x(1) is probably the constructor for the field X x in Y. Is the value of 1 (of x(1)) then passed to Y(int x) automatically although it is declared private in Y?
In the second code snippet, there is no construction actually going on—it's just a definition of the classes and constructors. The only "special" thing about it is that the body of Y's constructor is defined outside the class; it could be in a different file, for example. In this case, it's no different from putting the body directly into the class1:
class Y {
X x;
public:
Y(int x) : x(1) {}
};
When this constructor of Y is invoked, it constructs the member variable x by passing 1 to the X constructor taking int. The constructor of Y doesn't do anything else, i.e. it ignores its own parameter.
The syntax Y::Y used in the original code snippet is standard syntax for defining a member function outside of the class definition. For a non-constructor, it would look like this:
class Foo
{
int bar() const;
};
int Foo::bar() const
{
return 42;
}
1 With the slight difference that when put directly into the class definition, the function is implicitly inline (can be present in more than one translation unit).