Assigning a variable within a class with value of a method - c++

Is there a way to assign a variable within a class with a value of a class method?
I was trying the example below, but it is obviously not working. Is there a correct way of doing this?
#include <iostream>
using namespace :: std;
class rectangle
{
public:
rectangle(double h, double w) {
height = h;
width = w;
};
double area(void) {
return height*width;
};
double myarea = (*this).area();
private:
double height, width;
};
int main(void) {
rectangle r(2.5, 3);
cout << "Area is: " << r.area() << endl;
cout << "Area is: " << r.myarea << endl;
return 0;
}
result
Area is: 7.5
Area is: 0

The problem is that member variables are initialized in the order they are declared within the class. Also, your constructor creates the object before you have actually initialized width and height, as you do your initial assignment in the body of the constructor, rather than in an initializer list. Thus, when myarea is initialized (in your code), width and height have not yet been set.
To fix this, you can re-order the members and move the initialization of width and height into a list:
class rectangle {
private:
double height, width; // These will NOW be set before "myarea" is calculated
public:
rectangle(double h, double w) : height{ h }, width{ w } {
// Any assignments done here will be AFTER initialization of "myarea"
}
double area(void) {
return height * width;
}
double myarea = area();
};
Also, you don't need the complex (*this).area() syntax - just area() will do.
EDIT: Another thing to remember is that the setting of myarea by calling the area() function will only be done once (at object creation); if you change either width or height later, you won't (automatically) change myarea.

Related

create object with proporties

How to create an object in C++ with proporties?
If the object is an rectangle I want to access the height and the width like this
int height = obj.height;
int width = obj.width;
The object is returned by a function.. So what is the return type of the function?
Create a class Rectangle:
class Rectangle {
private:
int height;
int width;
public:
Rectangle(int h, int w) : height(h), width(w) {} // constructor to initialize width and height
void getHeight() { return height; } // public getters but private attributes to stick to the encapusaltion
void getWidth() { return width; }
};
Have a function returning a rectangle:
Rectangle doSomething() { // the return type is an instance of the class Rectangle
Rectangle r(2, 3); // create a rectangle with a height of 2 and a width of 3
return r; // return the created object
}
int main()
{
Rectangle r = doSomething(); // call your function
cout << r.getHeight() << " " << r.getWidth() << endl; // prompt width and height
}
If you want to access width and height via r.width and r.height change the access specifier private to public. Then you will not need the getters anymore.

expected constructor, destructor or header

This program contains three parts: the header, the functions for the class and the main part that is interactive. However, it won't compile.
I keep getting the response that there is an expected constructor, destructor or type conversion.
#ifndef BOX_H
#define BOX_H
class Box
{
private:
double height;
double width;
double length;
public:
Box();
double setHeight();
double setWidth();
double setLength();
double getVolume();
double getSurfaceArea();
};
#endif
function.cpp:
#include "Box.hpp"
/**********************************************************************
Box:: Box
This is the default constructor that uses the set methods to initialize each field to 1.
* **********************************************************************/
Box::Box()
{
height = 1;
width = 1;
length = 1;
}
/*
Does anyone know what this section does? Is it another default constructor or is is it even needed?
Box::Box(double height, double width, double length)
{
setHeight(height);
setWidth(width);
setLength(length);
}
*/
double Box::setHeight()
{
return height;
}
double Box::setWidth()
{
return width;
}
double Box::setLength()
{
return length;
}
double Box::getVolume()
{
return height * width * length;
}
double Box::getSurfaceArea()
{
double SurAre = 0;
SurAre = (2 * (length * width)) + (2 * (length * height)) + (2 * (height * width));
return SurAre;
}
main.cpp:
#include <iostream>
#include "Box.hpp" //contains Box class declaration
using namespace std;
int main()
{
Box object;
double Alength;
double Awidth;
double Aheight;
cout << "This program will calculate the area of a box.\n";
cout << "What is the length?";
cin >> Alength;
cout << "What is the width?";
cin >> Awidth;
cout << "What is the height?";
cin >> Aheight;
object.setLength(Alength);
if (!object.setWidth(Awidth))
cout << "Invalid box width entered. \n" << endl;
if (!object.setHeight(Aheight))
cout << "Invalid box height entered. \n" << endl;
cout << "Volume: " << object.getVolume() << endl;
cout << "Surface Area: " << object.getSurfaceArea() << endl;
return 0;
}
Does anyone have an idea about why?
If you uncomment the three-parameter constructor, you will get an error message, because a constructor is a class member, and class members have to be declared inside the class before they can be used or defined outside.
Add the line
Box(double height, double width, double length);
inside your class definition, and then the additional constructor can be compiled also.
C++ has some strange behaviors: if you fail to declare and define a default constructor, it will do it for you. Think autogenerated. It will also define a compiler-generated copy constructor and destructor. It's helpful to understand this, because these things exist whether you define them or not.
You both declared the constructor in the header:
public:
Box();
and defined it in the cpp file:
Box::Box()
You correctly both declared and defined this constructor.
If you want any other constructor, you have to declare it before you can define it as well
public:
Box();
Box(double height, double width, double length); // this is new
and then you can uncomment your definition in the cpp file, and all should be well.
One other style point: the way you've defined your 3 parameter constructor is not great style. What happens is that you construct a Box, and when you do so, you use the default constructor for it's member variables of height, width, and depth. You then call 3 member functions to assign these variables. In C++ you can avoid all this by using an initializer list. The body of your 3 parameter constructor becomes
Box::Box(double height, double width, double length) :
height(height), width(width), length(length)
{}
What this says is "build me a Box, and as you do so, use the value of passed in height for member height, width for member width, length for member length". You save yourself an assignment of 0 as a default value for the member variables and 3 function calls by building your Box "out of the box" as it were with those values. This uses the copy constructor for your member variables rather than their default constructors followed by an assignment.
(technical note: as builtins, doubles technically don't have these constructors, but the semantics behave as if they do, so you can think of them as having them on first order thought.)
This means, additionally, that if you define a copy constructor:
Box(const Box& other);
then you can use that in other classes to initialize a Box in their initializer lists, e.g.
BunchOfBoxes(const Box& firstBox) :
m_firstBox(firstBox)
{}
and it will use your copy constructor from the Box class to do the same sort of initialize-on-build for BunchOfBoxes
You have a problem with your class declaration/definition:
Your setters should have parameters so you can use them as setters.
In your Box.hpp change
double setHeight();
double setWidth();
double setLength();
to
double setHeight(double _height);
double setWidth(double _width);
double setLength(double _length);
Then in your Box.cpp change
double Box::setHeight()
{
return height;
}
double Box::setWidth()
{
return width;
}
double Box::setLength()
{
return length;
}
to
double Box::setHeight(double _height)
{
height = _height;
return height;
}
double Box::setWidth(double _width)
{
width = _width;
return width;
}
double Box::setLength(double _length)
{
length = _length;
return length;
}

Confused with variables in classes

I'm a bit confused with classes was hoping some one could explain.
I have a class I'm making to create buttons for a game menu. There are four variables:
int m_x
int m_y
int m_width
int m_height
I then want to use a render function in the class but Im not understanding how i use the 4 int variables in the class and pass it to the function in the class?
My class is like this:
class Button
{
private:
int m_x, m_y; // coordinates of upper left corner of control
int m_width, m_height; // size of control
public:
Button(int x, int y, int width, int height)
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
}
void Render(SDL_Surface *source,SDL_Surface *destination,int x, int y)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( source, NULL, destination, &offset );
}
} //end class
Where i am confused is how the values created in public:Button is passed to void render I'm not fully sure I've got this right, if i have its pure luck so far because I'm still a little bit confused.
Maybe an example will help:
#include <iostream>
class Button
{
private:
int m_x, m_y; // coordinates of upper left corner of control
int m_width, m_height; // size of control
public:
Button(int x, int y, int width, int height) :
//This is initialization list syntax. The other way works,
//but is almost always inferior.
m_x(x), m_y(y), m_width(width), m_height(height)
{
}
void MemberFunction()
{
std::cout << m_x << '\n';
std::cout << m_y << '\n';
//etc... use all the members.
}
};
int main() {
//Construct a Button called `button`,
//passing 10,30,100,500 to the constructor
Button button(10,30,100,500);
//Call MemberFunction() on `button`.
//MemberFunction() implicitly has access
//to the m_x, m_y, m_width and m_height
//members of `button`.
button.MemberFunction();
}
You might want to spend some time learning C++ before getting too deep into a complex programming project.
To answer your question, The variables initialized in the constructor (Button) are part of the class instance. So they're available within any class method, including Render.

Unable to access the base variables in the derrived class

The following compiled code is showing the resulting area of zero. Some how the width and height variables are still remaining as zero even though we set it using the base constructor.
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0)
{
Shape(a, b);
}
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0)
{
Shape(a, b);
}
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// store the address of Rectangle
shape = &rec;
// call rectangle area.
cout << shape->area() << endl;
// store the address of Triangle
shape = &tri;
// call triangle area.
cout << shape->area() << endl;
return 0;
}
Output:
Rectangle class area :
0
Rectangle class area :
0
Trying to find out why the area is zero and how to make the pgm to print the actual area ?
The correct syntax is:
Rectangle( int a=0, int b=0) : Shape(a, b)
{ // ^^^^^^^^^^^^
}
You need to call Shape constructor as part of initializer list.
As in your example, if you write it as a statement,
{
Shape(a,b); // <--- no effect on Base part
}
then, a temporary Shape object is created and destroyed, so it has no effect.
your constructor of child class should be like following,
Rectangle( int a=0, int b=0)
:Shape(a, b) //call base class constructor
{
//Shape(a, b); // you are creating new object of shape here , not calling base constructor
}

How to store the state of an object without using global variables in c++

I'm new to C++ and while learning i came across a lot of places which say that using global variables should be avoided and used in very rare cases.
My question is, How can i store the state of an object so then it can be accessed at a later time without using global variables? Here's an example:
A Circle class may have its state stored by using diameter, x and y as globals. Then these values can be modified and retrieved with methods.
Is there a way to accomplish the above without using globals that is preferred?
Thanks
Edit:
I had globals confused with member variables and that was the problem. Now i feel really stupid for asking this question but hopefully this will help someone else.
You normally store an object's state using member variables.
class Circle
{
...
private:
double x, y;
double diameter;
};
Wanting to store an object's state in global variables is really bizarre because then you could only have one object.
If you use globals to store the state of the Circle, then you can only have one Circle at any time, because if you had two, they would both be trying to use the same global variables to store their state, and that would be messy.
Make state variables member variables, so that each class instance has its own version of them. This is one of the principles of object oriented programming.
If you have variables that need to be shared between all instances of the class, make them static member variables. That way you know only your objects can access them (if you choose to use private or protected visibility on them) and no one else who doesn't know what they're doing will come in a screw with them.
Example:
class Circle {
public:
Circle(double x, double y, double diameter) : x(x), y(y), diameter(diameter) { }
double X() const { return x; }
double Y() const { return y; }
double diameter() const { return diameter; }
...
private:
double x, y, diameter;
};
Now when we have two Circles, they behave fine:
Circle c1(4.0, 4.0, 6.0);
Circle c2(1.0, 6.0, 3.0);
cout << c1.X() << endl
<< c2.X() << endl;
// prints 4 and 1
But if we do it this way, with globals:
// BAD, DON'T DO THIS
double x = 0, y = 0, diameter = 0;
class Circle {
public:
Circle(double _x, double _y, double _diameter) {
x = _x, y = _y, diameter = _diameter;
}
double X() const { return x; }
double Y() const { return y; }
double diameter() const { return diameter; }
};
When we have two circles:
Circle c1(4.0, 4.0, 6.0);
Circle c2(1.0, 6.0, 3.0);
cout << c1.X() << endl
<< c2.X() << endl;
// prints 1 and 1
The last Circle you create will overwrite all the other Circles' data. As you can see, that's not a good thing.
There are three kind of variables in C++:
Global variables
Member variables
Local variables
An example might help:
const float pi = 3.14; // A global variable. Always the same value.
class Circle
{
private:
float radius; // Member variable.
public:
Circle(float radius=0) { this.radius = radius; }
float GetRadius() { return radius; }
float GetDiameter() { return radius * 2; }
float GetArea() { return pi * radius * radius; }
}
void PrintCircle(Circle& c, char* name)
{
cout << name << " Radius: " << c.GetRadius() << ", Diameter: " << c.GetDiameter()
<< ", Area: " << c.GetArea();
}
void ShowCircle(float radius)
{
Circle unit(1); // Local variable
Circle c(radius); // Local variable
PrintCircle(unit, "Unit circle");
PrintCircle(c, "My circle");
}
int main(int argc, int** argv)
{
ShowCircle(2);
ShowCirlce(3);
}