C++ not modifiable lvalue - c++

When I run this code, I get the an error saying C.getRadius() isn't modifiable lvalue:
#include <iostream>
#include <conio.h>
using namespace std;
class Circle {
double x, y, r;
public:
Circle (double a=1.0, double b=1.0, double c=1.0) { x=a; y=b; r=c; }
~Circle() {}
double Area();
double getRadius();
};
class Conus {
double height;
Circle C;
public:
Conus (double , double , double , double );
~Conus() {};
double Volume();
void setRadius(double );
};
Conus::Conus(double h, double a, double b, double c)
: C (a, b, c)
{
height=h;
}
double Circle::Area() { return r*r*3.14; }
double Conus::Volume() { return C.Area()*height; }
double Circle::getRadius() { return r; }
void Conus::setRadius(double t ) { C.getRadius()=t; }
int main() {
double a=2.4, b=3.5, r=5.4, h=5.9;
Circle Wre (a, b, r) ;
Conus Konusi (h, a, b, r) ;
cout << "Wris centris koordinatebia: " << a << " da " << b << ", radiusi: " << r
<< ". Wris fartobia :" << Wre.Area() << endl;
cout << "Konusis fudzis centris koordinatebia: " << a << " da " << b << ", radiusi: " << r
<<endl<< "konusis moculobaa: " << Konusi.Volume() << endl;
Konusi.setRadius(r+3);
cout << Konusi.Volume() << endl;
_getch();
return 0;
}

getRadius() returns a copy of the object's radius, not a reference to it, so you can't use it for modification. So the following expression:
C.getRadius()=t;
attempts to modify a temporary copy, which isn't allowed. (The reason that its not allowed is that otherwise that code would compile but do nothing useful, giving a subtle bug rather than an easily identified compile error).
There are various options:
return a reference, double & getRadius();
add a void setRadius(double); function, and use that for modification
make the radius public; there's little point in using accessors unless they're necessary to enforce invariants.
If you do want accessor functions, you should keep the existing double getRadius(), but declare it const. That will allow you to get, but not modify, the radius of a constant object.

This is a not a correct assignment, you are attempting to modify a temporary copy of the r not r itself:
C.getRadius()=t;
One way to fix this would be to add this method to Circle:
void setRadius( double t ){ r = t ; }
and call like:
void Conus::setRadius(double t ) { C.setRadius( t ); }
this is a great article Understanding lvalues and rvalues in C and C++ and the first example is similar to the problem you were facing just now.

Related

Problem with the declaration of the parameters in one of the Classes method [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed last month.
I was trying to write some code with classes instead of structures (Some task that our proffesor gave us), The task is to convert from Cartesian to Spherical and the other way around, so dont bother with some finesses (namespace, encapsulation...) that is not accented in this very example. I encountered a very silly error that i haven't seen so far, and i am unfortunately unable to solve it..
If you pay attention you will see that there are two methods with identical names (ToMe(...)) and even parameters (The only difference is the parameter type). When i run this code with declaration of the ToMe procedure in Decard Class commented i get the desired result, but when i want to run it in this shape it says the following:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2143: syntax error: missing ',' before '&'
error C2065: 'S': undeclared identifier
Does anyone have any clue to why it keeps breaking?
#include<iostream>
#include<math.h>
using namespace std;
class Decard
{
double m_x;
double m_y;
double m_z;
public:
Decard() :m_x{0}, m_y{ 0 }, m_z{ 0 } {}
Decard(double x, double y, double z) :m_x{ x }, m_y{ y }, m_z{ z }{}
double GetX() const { return m_x; }
double GetY() const { return m_y; }
double GetZ() const { return m_z; }
void Ucitaj()
{
cout << "Unesite koordinate tacaka u dekartovom koordinatnom sistemu x,y, i z respektivno" << endl;
cin >> m_x >> m_y >> m_z;
}
void ToMe(const Spheric& S) //THIS IS THE LINE THAT MAKES PROBLEMS
{
m_x = S.GetR() * sin(S.GetTheta()) * cos(S.GetPhi());
m_y = S.GetR() * sin(S.GetTheta()) * sin(S.GetPhi());
m_z= m_x = S.GetR() * cos(S.GetTheta());
}
void Print()
{
cout << "U dekartovom :" << endl;
cout << "X:" << m_x << endl << "Y:" << m_y << endl << "Z:" << m_z << endl;
}
};
class Spheric
{
double m_r;
double m_phi;
double m_theta;
public:
Spheric() :m_r{ 0 }, m_phi{ 0 }, m_theta{ 0 } {}
Spheric(double x, double y, double z) :m_r{ x }, m_phi{ y }, m_theta{ z }{}
void Ucitaj()
{
cout << "Unesite koordinate tacaka u sfernom koordinatnom sistemu r,fi, i teta respektivno" << endl;
cin >> m_r >> m_phi >> m_theta;
}
void Print()
{
cout << "U sfernom :" << endl;
cout << "R:" << m_r << endl << "Phi:" << m_phi << endl << "Theta:" << m_theta<< endl;
}
void ToMe(const Decard& D)
{
m_r = sqrt(pow(D.GetX(), 2) + pow(D.GetY(), 2) + pow(D.GetZ(), 2));
m_phi = atan(D.GetY() / D.GetX());
m_theta = atan(D.GetZ() / m_r);
}
double GetR() const { return m_r; }
double GetPhi() const { return m_phi; }
double GetTheta() const { return m_theta; }
};
int main()
{
Decard D{ 1,2,3 };
Spheric S;
S.ToMe(D);
S.Print();
D.ToMe(S);
D.Print();
return 0;
}
What i have tried is placing the definition of the procedure outside of the class:
void Decard::ToMe(const Spheric& S)
{
.
.
.
}
And i saw something interesting, Visual Studio pointed out that the parameter type of this outplaced defenition does not match "const <error_type> &S" in the declaration of the procedure.
You need a forward declaration. Like this
class Spheric; // forward declaration
class Decard
{
...
void ToMe(const Spheric& S); // not defined yet
...
};
class Spheric
{
...
};
// now Decard::ToMe can be defined
inline void Decard::ToMe(const Spheric& S)
{
m_x = S.GetR() * sin(S.GetTheta()) * cos(S.GetPhi());
m_y = S.GetR() * sin(S.GetTheta()) * sin(S.GetPhi());
m_z= m_x = S.GetR() * cos(S.GetTheta());
}
The foeward declaration allows you to mention the class Spheric but not to use it. So the definition of Decard::ToMe must be postponed until both classes have been fully defined.

Error while adding Complex numbers

In below program I am getting 2 errors at below lines.
r = sum(p,q); //Function sum should have a prototype.
r = sum(p,q); //Cannot convert int to complex
Kindly advise the changes in the code.
Note: I have to do the code by passing objects of complex class to add and also the addition should return a complex number.
#include<iostream.h>
#include<conio.h>
class Complex
{
private:
int real;
int imag;
public:
void getNo()
{
cout<<"Enter real part : "<<endl;
cin>>real;
cout<<"Enter imaginary part : "<<endl;
cin>>imag;
}
void showNo()
{
cout<<real<<"+"<<imag<<"i";
}
Complex sum(Complex, Complex);
};
Complex Complex :: sum(Complex c1, Complex c2)
{
Complex a;
a.real = c1.real + c2.real;
a.imag = c1.imag + c2.imag;
return a;
}
void main()
{
clrscr();
Complex p,q,r,s;
p.getNo();
q.getNo();
cout<<endl<<"First complex number is : ";
p.showNo();
cout<<endl<<"Second complex number is : ";
q.showNo();
r = sum(p,q);
cout<<"Addtion of the complex no is : ";
r.showNo();
getch();
}
For your purpose the "sum" function should not be in the "Complex" class. Here a bit changed code:
#include <iostream>
#include <conio.h>
using namespace std;
class Complex
{
public:
int real;
int imag;
void getNo ()
{
cout << "Enter real part : " << endl;
cin >> real;
cout << "Enter imaginary part : " << endl;
cin >> imag;
}
void showNo ()
{
cout << real << "+" << imag << "i";
}
};
Complex sum (Complex c1, Complex c2);
int main ()
{
//clrscr ();
Complex p, q, r, s;
p.getNo ();
q.getNo ();
cout << endl << "First complex number is : ";
p.showNo ();
cout << endl << "Second complex number is : ";
q.showNo ();
r = sum (p, q);
cout << endl << "Addtion of the complex no is : ";
r.showNo ();
getch ();
}
Complex sum (Complex c1, Complex c2)
{
Complex
a;
a.real = c1.real + c2.real;
a.imag = c1.imag + c2.imag;
return a;
}
Edit
Functions in class require an instance (object) of class.
Simply you CAN do this:
p.getNo();
t.sum();
myComplexNum.getReal();
But in your code you are trying to do this which you CAN NOT:
a = getNo();
b = sum();
getReal();
Additionally you CAN make the function static like other answer.
static functions and variables does not require an instance. Calling:
// We have 1 Box named b
Box b;
b.setHeight(5);
b.setWidth(3);
b.setDepth(3);
//ClassName::StaticVariable;
int c1 = Box::count; // returns 1
//ClassName::StaticFunction(Parameters);
int c2 = Box::getCount(); // returns 1
When you declare a function (a method) in a class, this method can be called on a instance of this class (a object).
In the given code the function Complex sum (Complex c1, Complex c2); should be called on an object of type Complex.
But as the function doesn't change anything inside the object, it rather creates a new object and returns it, you should better declare a static method.
static Complex sum(Complex, Complex);
in this case you can call the function without an existing Complex object.
The syntax is the following :
r = Complex::sum(a, b);

(C++) Constructor, default parameters, "call of overloaded... ambigous"

i'm new to this site, after doing some research I could not find a problem similar to mine(some questions looked like mine but their code was different)
So basically what i'm trying to do is to representing the framebuffer matrix with all different colors values. I'm coding a class named "Point", and I have one constructor, using default arguments, here it is :
Point.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
class Point
{
protected:
int x;
int y;
public:
Point(int=0,int=0);
Point(const &Point);
void showC() const;
static void showC(Point);
virtual ~Point();
};
#endif // POINT_H
Point.cpp
#include "Point.h"
using namespace std;
Point::Point(int a,int b)
{
x=a;
y=b;
}
Point::~Point()
{}
void Point::showC() const
{ cout << x << " " << y << endl; }
void Point::showC(Point P)
{ cout << P.x << " " << P.y << endl; }
But the problem is when I try to compile the program
main.cpp
#include <iostream>
#include "Point.h"
using namespace std;
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
cout << "Call of function member showC\n";
P1.showC();
P2.showC();
P3.showC();
cout << "Call of static function showC\n";
Point::showC(P1);
Point::showC(P2);
Point::showC(P3);
return 0;
}
There is an error when I create Point P2 :
"Call of overloaded 'Point(int)' is ambigous"
On all the others question i read, either it was not the same problem or they had a default constructor in addition to a constructor with default argument which cause ambiguity of which constructor to use if you create an object without argument.
On a book i'm reading to improve skills on c++, there is this sample that is working somehow, and that's why I don't really understand
Here is the sample :
main.cpp
class point
{
private :
int x;
int y;
Point (int abs=0, int ord=0) //inline constructor
{x=abs; y=ord;}
bool coincide(point);
};
bool point::coincide(point pt)
{ return ( (pt.x==x) && (pt.y==y) );
}
int main()
{
point a, b(1), c(1,0);
cout << "a and b : " << a.coincide(b) << " ou " b.coincide(a) << "\n"
cout << "b et c : " << b.coincide(c) << " ou " << c.coincide(b) << "\n"
}
However he grouped everything in the main.cpp files, and his constructor is inline.
Can anyone explain to me why is the sample working, and why my program is not ? I guess there is a mechanism that i don't understand...
Thanks in advance
RE-EDIT : I copied all the code
I think you are mixing both python and c++ way of creating class
python do use : class Point:
for declaring in class , c++ uses {} like class Point {};
Below works by changing the class declaration.
Just added a cout in your constructor
#include <iostream>
#include <vector>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int=0,int=0);
};
Point::Point(int a, int b)
{
x = a;
y = b;
cout<<x<<y<<endl;
}
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
return 0;
}
Output
00
20
4-7
Program ended with exit code: 0
After question edit
Removed your buggy line and it works perfectly
Point(const &Point);
#include <iostream>
#include <vector>
using namespace std;
class Point
{
protected:
int x;
int y;
public:
Point(int=0,int=0);
//Point(const &Point);
void showC() const;
static void showC(Point);
virtual ~Point();
};
Point::Point(int a,int b)
{
x=a;
y=b;
}
Point::~Point()
{}
void Point::showC() const
{ cout << x << " " << y << endl; }
void Point::showC(Point P)
{ cout << P.x << " " << P.y << endl; }
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
cout << "Call of function member showC\n";
P1.showC();
P2.showC();
P3.showC();
cout << "Call of static function showC\n";
Point::showC(P1);
Point::showC(P2);
Point::showC(P3);
return 0;
}
Output
Call of function member showC
0 0
2 0
4 -7
Call of static function showC
0 0
2 0
4 -7
Program ended with exit code: 0
After edit I guess you want to use copy constructor just change it to
Point(const Point &p2) {x = p2.x; y = p2.y; }

Addition of complex numbers using classes

I am trying to add 2 complex numbers together, but i am getting the errors:
no operator "+" matches these operands
no operator "<<" matches these operands
#include <iostream>
using namespace std;
class complex
{
public:
double get_r() { return r; }
void set_r(double newr) { r=newr; }
double set_i() { return i; }
void set_i(double newi) { i = newi; }
private:
double r, i;
};
int main()
{
complex A, B;
A.set_r(1.0);
A.set_i(2.0);
B.set_r(3.0);
B.set_i(2.0);
complex sum = A+B;
cout << "summen er: " << sum << endl;
system("PAUSE");
return 0;
};
I'm very new to programming, but i can't see why it won't add these numbers together. What have I done wrong?
You must overload operators + and << (and each one in your need) for your defined classes. Note that operators are no more than specific functions with specific definition syntax (operator+, for example: C = A + B could be understood as C = A.sum(B)). Here a link about http://en.cppreference.com/w/cpp/language/operators
Operator + is defined for builtin types and for some types from the standard library. As complex is here a custom class, you must define all operators that should act on it.
operator + could be defined as:
class complex {
...
complex operator + (const complex& other) {
return complex(get_r() + other.get_r(), get_i() + other.get_i());
}
...
};
Beware that does allow neither A++ nor A-B. They would require (resp.) complex & operator ++() or complex operator - (const complex &).
For stream insertion, the first parameter is the stream itself, so you must define a friend operator with 2 parameters outside the class:
outstream& opererator << (outstream &out, const complex& val) {
// output it the way you want
return out;
}
Complex numbers are part of the C++ standard. Here is the example from http://en.cppreference.com/w/cpp/numeric/complex.
#include <iostream>
#include <iomanip>
#include <complex>
#include <cmath>
int main()
{
using namespace std::complex_literals;
std::cout << std::fixed << std::setprecision(1);
std::complex<double> z1 = 1i * 1i;
std::cout << "i * i = " << z1 << '\n';
std::complex<double> z2 = std::pow(1i, 2);
std::cout << "pow(i, 2) = " << z2 << '\n';
double PI = std::acos(-1);
std::complex<double> z3 = std::exp(1i * PI);
std::cout << "exp(i * pi) = " << z3 << '\n';
std::complex<double> z4 = 1. + 2i, z5 = 1. - 2i;
std::cout << "(1+2i)*(1-2i) = " << z4*z5 << '\n';
}
Trying to implement a class complex yourself would require you define addition, equality, and ostream. And you would only have 5% of a fully implemented class. Looking at the header itself will reveal how those that wrote the C++ standard library implemented the whole thing.
All the arithmetic operators like plus, minus, multiply or divide only work with pre defined data types, like int, char, float etc.
Now if you want to add something in a class, you have to use the fundamental aspect of OO programming that is operator overloading.
Here is how you can achieve it.
#include <iostream>
using namespace std;
class complex
{
float x, y;
public:
complex()
{
}
complex(float real, float img)
{
x = real;
y = img;
}
friend complex operator+(complex,complex);
void display(void);
};
complex operator+(complex c,complex d)
{
complex t;
t.x = d.x + c.x;
t.y = d.y + t.y;
return(t);
};
void complex::display(void)
{
cout << x << "+i" << y << endl;
}
int main()
{
complex c1, c2, c3;
c1 = complex(2.5, 3.5);
c2 = complex(1.5, 5.5);
c3 = c1 + c2;//c3=opra+(c1,c2)
cout << "C1:" << endl;
c1.display();
cout << "C2:" << endl;
c2.display();
cout << "C3:" << endl;
c3.display();
}

Derived Classes Error

I finished a small program using derived classes and it compiles correctly, but the output is wrong.
The program uses an ordered pair (x, y) as the center for a circle. It then uses the center and the radius given to determine the area and circumference of the circle.
Outputting ordered pairs with the pointType class works fine, but when I tested the circleType class I expected to get (0, 0) as a default. Instead I got (2293512, 2293700)
Any help given will be appreciated!
Here's the point class code:
#ifndef POINTTYPE_H_INCLUDED
#define POINTTYPE_H_INCLUDED
#include <iostream>
class pointType{
public:
pointType (int=0, int=0);
int getX() const;
int getY() const;
void setX(int);
void setY(int);
void setValues(int, int);
friend pointType operator + (pointType, pointType);
friend pointType operator - (pointType, pointType);
friend std::ostream& operator << (std::ostream&, pointType);
private:
int x;
int y;
};
#endif // POINTTYPE_H_INCLUDED
Here's the point class implementation:
#include "pointType.h"
pointType::pointType (int X, int Y) : x(X), y(Y) {}
int pointType::getX () const {
return x;
}
int pointType::getY () const {
return y;
}
void pointType::setX (int new_x) {
x = new_x;
}
void pointType::setY (int new_y) {
y = new_y;
}
void pointType::setValues (int new_x, int new_y) {
x = new_x;
y = new_y;
}
pointType operator + (pointType lh, pointType rh){
pointType answer;
answer.x = lh.x + rh.x;
answer.y = lh.y + rh.y;
return answer;
}
pointType operator - (pointType lh, pointType rh){
pointType answer;
answer.x = lh.x - rh.x;
answer.y = lh.y - rh.y;
return answer;
}
std::ostream& operator << (std::ostream& out, pointType c){
out << "(" << c.x << ", " << c.y << ")";
return out;
}
Here's the circle class:
#ifndef CIRCLETYPE_H_INCLUDED
#define CIRCLETYPE_H_INCLUDED
#include "pointType.h"
#include <iostream>
class circleType: protected pointType {
public:
circleType (float=0);
circleType (int=0, int=0);
void setRadius (float);
float calculateArea (float);
float calculateCircumference (float);
friend std::ostream& operator << (std::ostream&, circleType);
private:
float radius;
int center_x;
int center_y;
};
#endif // CIRCLETYPE_H_INCLUDED
Here's the circle class implementation:
#include "pointType.h"
#include "circleType.h"
#include <math.h>
const float PI = 3.14;
circleType::circleType(float R): radius(R) {}
circleType::circleType(int center_X, int center_Y):
pointType(center_x, center_y) {}
void circleType::setRadius(float new_radius) {
radius = new_radius;
}
float circleType::calculateArea(float radius) {
float area;
area = PI * pow(radius, 2);
return area;
}
float circleType::calculateCircumference(float radius) {
float circumference;
circumference = PI * (radius * 2);
return circumference;
}
std::ostream& operator << (std::ostream& odata, circleType f) {
odata << "(" << f.center_x << ", " << f.center_y << ")";
return odata;
}
Here's the testing code:
#include "pointType.h"
#include "circleType.h"
#include <iostream>
#include <math.h>
using namespace std;
int main() {
pointType c, d(8, 9);
circleType f(4, 5);
cout << c << endl;
cout << d << endl;
c.setValues(12, 3);
cout << c << endl;
cout << c + d << endl;
cout << c - d << endl;
cout << f << endl;
return 0;
}
As far as I can see, the circleType int members center_x and center_y are never set. Your constructor CircleType::CircleType(int=0,int=0) calls the base constructor, which in turn set pointType.x and pointType.y, both private members of the base class (and hence not available to circleType).
My suggestion (or what I think you intended\expected): make int x and int y protected, not private, and remove center_x and center_y, then print odata << "(" << f.x << ", " << f.y << ")";
Its a typo.
circleType::circleType(int center_X, int center_Y):
pointType(center_x, center_y) {}
Notice the difference between center_X (uppercase) and center_x (lowercase).
You pass your uninitialized members to the parent constructor which can have any value lingering at the stack.
Therefor it is good practive to always preceed your members with m_ e.g: m_centerX. (In this particular case it isnt even neccessary to have them again in the child class, redundancy is bad!)
EDIT:
Sorry for the confusion, but please be more precisly next time, could have saved us all alot of time. I assumed that your problems occurs when adding a point with a circle, after running the code by my own I noticed that it happens when outputting f. The reason is the same as explained above: you dont initialize your members! They simply hold any value which were currently at the memory location the object becomes constructed.
In your circleType class, center_x and center_y aren't being initialised. The parameters are being passed directly to the pointType constructor and setting the private members. You can prove this by changing the operator<< function that takes a circleType argument:
std::ostream& operator << (std::ostream& odata, circleType f) {
odata << "(" << f.center_x << ", " << f.center_y << ")" << std::endl;
odata << "(" << f.getX() << ", " << f.getY() << ")"; //access superclass
return odata;
}
With protected inheritance, you also can't use the + and - overloads defined for the base class either, it won't compile.