Using an object of separate class in a class constructor - c++

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) {}

Related

How to pass int as rvalue argument to a function or constructor?

In the following code the class A has 2 constructors, one taking int by value and the other taking int by rvalue reference. How to create an object using the second constructor call.
#include <iostream>
using namespace std;
class A
{
public:
A(int i) : r_i(i)
{
cout<<endl<<"A(inti)";
}
A(int&& i) : r_i(i)
{
cout<<endl<<"A(int&&)";
}
private:
int &r_i;
};
int main()
{
int j = 5;
A a(j); // Works
A b(std::move(j)); // Error [1]
}
Error [1] : call of overloaded ‘A(std::remove_reference<int&>::type)’ is ambiguous
Which c++ rule prevents the call to rvalue constructor ?

whenever i try to run this code it gives me an error

#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);

Initializing A Variable With Its Default Constructor

Question:
Is there a difference between the following initializations?
(A) What exactly is the second one doing?
(B) Is one more efficient than the other?
int variable = 0;
int variable = int();
This question also applies to other data types such as std::string:
std::string variable = "";
std::string variable = std::string();
Background:
I basically got the idea here (the second code sample for the accepted answer) when I was trying to empty out a stringstream.
I also had to start using it when I began learning classes and realized that member variable initializations had to be done in the constructor, not just following its definition in the header. For example, initializing a vector:
// Header.h
class myClass
{
private:
std::vector<std::string> myVector;
};
// Source.cpp
myClass::myClass()
{
for (int i=0;i<5;i++)
{
myVector.push_back(std::string());
}
}
Any clarity on this will be greatly appreciated!
Edit
After reading again, I realized that you explicitely asked about the default constructor while I provided a lot of examples with a 1 parameter constructor.
For Visual Studio C++ compiler, the following code only executes the default constructor, but if the copy constructor is defined explicit, it still complains because the never called copy constructor can't be called this way.
#include <iostream>
class MyInt {
public:
MyInt() : _i(0) {
std::cout << "default" << std::endl;
}
MyInt(const MyInt& other) : _i(other._i) {
std::cout << "copy" << std::endl;
}
int _i;
};
int main() {
MyInt i = MyInt();
return i._i;
}
Original (typo fixed)
For int variables, there is no difference between the forms.
Custom classes with a 1 argument constructor also accept assignment initialization, unless the constructor is marked as explicit, then the constructor call Type varname(argument) is required and assignment produces a compiler error.
See below examples for the different variants
class MyInt1 {
public:
MyInt1(int i) : _i(i) { }
int _i;
};
class MyInt2 {
public:
explicit MyInt2(int i) : _i(i) { }
int _i;
};
class MyInt3 {
public:
explicit MyInt3(int i) : _i(i) { }
explicit MyInt3(const MyInt3& other) : _i(other._i) { }
int _i;
};
int main() {
MyInt1 i1_1(0); // int constructor called
MyInt1 i1_2 = 0; // int constructor called
MyInt2 i2_1(0); // int constructor called
MyInt2 i2_2 = 0; // int constructor explicit - ERROR!
MyInt2 i2_3 = MyInt2(0); // int constructor called
MyInt3 i3_1(0); // int constructor called
MyInt3 i3_2 = 0; // int constructor explicit - ERROR!
MyInt3 i3_3 = MyInt3(0); // int constructor called, copy constructor explicit - ERROR!
}
The main difference between something like:
int i = int(); and int i = 0;
is that using a default constructor such as int() or string(), etc., unless overloaded/overridden, will set the variable equal to NULL, while just about all other forms of instantiation and declarations of variables will require some form of value assignment and therefore will not be NULL but a specific value.
As far as my knowledge on efficiency, neither one is "better".

error: non-aggregate type 'Circle' cannot be initialized with an initializer list

I'm in need of help with an assignment for my C++ class. My problem is trying to compile a program I got from my professor. Every time I try to compile the code I get the following error
"error: non-aggregate type 'Circle' cannot be initialized with an initializer list
Circle list[] ={ { 93, "yellow" },
same error follows for the second circle in the array. Can someone tell me what I need to do to get this code to compile?
#include <iostream>
#include "Circle.h"
#include <string>
using namespace std;
int main()
{
Circle list[] ={ { 93, "yellow" },
{ 27, "red" }
};
Circle *p;
p = list;
cout<<(*p).getRadius()<<endl;
cout<<(*p).getColor()<<endl;
cout<<p->getRadius()<<endl;
cout<<p->getColor()<<endl;
p++;
cout<<(*p).getRadius()<<endl;
cout<<(*p).getColor()<<endl;
cout<<p->getRadius()<<endl;
cout<<p->getColor()<<endl;
return 0;
}//end main
What version of C++ are you using? Before C++11, any class with at least one constructor could not be constructed using an aggregate list:
struct A
{
std::string s;
int n;
};
struct B
{
std::string s;
int n;
// default constructor
B() : s(), n() {}
};
int main()
{
A a = { "Hi", 3 }; // A is an aggregate class: no constructors were provided for A
B b; // Fine, this will use the default constructor provided.
A aa; // fine, this will default construct since the compiler will make a default constructor for any class you don't provide one for.
B bb = { "Hello", 4 }; // this won't work. B is no longer an aggregate class because a constructor was provided.
return 0;
}
I daresay Circle has a constructor defined, and cannot be constructor with an aggregate initialisation list pre C++11. You could try:
Circle list[] = { Circle(93, "Yellow"), Circle(16, "Red") };

no matching function for call to ‘myclass::myclass()’

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);