I am currently working on Chapter 7 in the book "Starting Out With C++ Early Objects" by the Pearson printing company.
I am unable to understand the function of the variable 'r' in this class declaration:
class Circle
{ private:
double radius;
public:
void setRadius(double r)
{ radius = r; }
double getArea()
{ return 3.14 * pow(radius, 2); }
};
Why can't I just write the 'radius' variable like this?
class Circle
{ private:
double radius;
double getArea()
{ return 3.14 * pow(radius, 2); }
};
I don't understand the function of the
public:
void setRadius(double r)
{ radius = r; }
Statement.
The technical reason is "because radius is private, hence inaccessible from outside the class".
So a change to radius must be some how managed by a public member function like SetRadius.
If the question now becomes "why designers did it that way, and did not simple make radius public?", well ... this is a never ending debate about how a proper object-oriented design should be an what has to be public and what not inside an object.
Traditional OOP school tends to make all data "private" and access or modify them through a variety of function to enforce what they call "encapsulation", and to have life easier in case the interface need to be extended to support eventual callbacks or events.
In this trivial simple case, well... all looks like a waste of energy (and without proper compiler optimization IS a waste of energy! In true physical sense). But may be they needed a uniform interface with something else.
As the functional behaviour of private is explained in other answers, directly accesing a private member outside the class will give you a compile-time error.
If you are asking why do we use setter functions and make some members private is a matter of design. For example; if you need the radius to be always positive number, you can write the set function as;
void setRadius(double r)
{
if(radius >= 0)
radius = r;
else
radius = 0;
}
Thus, you will have control over the values of the member when they are tried to be modified outside the class.
The radius is private. Without that function, you would not be able to set the radius from outside of the class. In order for the class to be useful, you would most likely want to be able to create objects of the type Circle and set their radius. Thus, you need some type of function in order to set that radius.
The easiest and most reasonable way to solve this is to supply a public member function inside the class Circle itself.
This can most easily be done using a setter, such as what you have shown. This allows you to set, and later change, the radius.
void SetRadius(float r)
{
radius = r;
}
You could also supply an extra argument to the constructor to ensure that a Circle always has its radius initialized with a user-supplied value, or at least set a default value in the declaration of radius (in C++11).
The concept of public private that no one can access the private variables just the class methods, and you can only access the public methods from your main function so ,the function setRadius is responsible to set the private variable of the radius
public:
void setRadius(double r)
{ radius = r; }
because the radius is a private variable so you have to create a public function inside the class to set that variable so you can set the radius when you create Circle object by :
this will work to set the radius in the main
Circle * test = new Circle;
test.setRadius(7);
but if you tried to set the radius directly by :
Circle * test = new Circle;
test.radius = 7;
it will crash the program Cannot access class private method
Related
Let say that I have a big class Circle with a lot of members and functions. To proceed a large amount of data I decided to create class PotentialCirlce (with only 3 members - x, y, r), do most of preprocessing based on PotentialCirlce and in the last stage create objects Circle.
a) is it correct approach? do It influence on performance or rather should I use only Circle.
It seems to me that I can use inheritance:
class potentialCircle {
protected:
point_t center;
unsigned int radius;
public:
potentialCircle(int a, int b, unsigned int r) : center{ point_t(a,b) }, radius{ r } {}
potentialCircle() = delete;
potentialCircle(const potentialCircle&) = default;
potentialCircle(potentialCircle&&) = default;
potentialCircle& operator=(const potentialCircle&) = default;
potentialCircle& operator=(potentialCircle&&) = default;
virtual ~potentialCircle() = default;
};
class Circle : public potentialCircle {
// members detected based on Hough Circle Transform
//point_t center; // coordinates of center point
point_t alternative_center; // needed when center is out of frame
//unsigned int radius; // radius
// members calculated based on Flood Fill algorithm (more realistic)
unsigned int area = 0;
float diameter = 0;
float perimeter = 0;
....
};
b) where should I put method which needs to compare two difference objects? one object of type Circle and one of PotentialCirle?
currently, I have defined below function as part of Circle
bool Circle::is_greater(const std::pair<potentialCircle, int>& point_pair) const;
but I don't have access to protected data members of potentialCircle, although Circle is inheriting from potentialCircle.
Maybe I should defined is_greater() as part of namepsace and make it a friend to Circle and potentialCircle.
Do you have better idea?
There are not really a good approach to compare objects of different types as it make little sense in practice. What would be the purpose of such comparisons.
Now even if you have a single class, if the ordering is not intransic to the type, it would be better to use an external class for sorting.
class CircleDiameterLess
{
public:
bool operator()(const Circle &lhs, const Circle &rhs)
{
return lhs.diameter < rhs.diameter;
}
};
That way, you can have multiple ways to sort data and it play nice with STL.
Another problem with your code if that it make little sense to have a class circle with a diameter that derives from a class potentialCircle with a radius. Your code will be hard to maintain because it is hard to understand.
You want to store either the diameter or the radius and compute the other one.
unsigned int get_diameter() const { return radius * 2; }
Member like alternative_center make no sense. A circle has only one center. If your class does not respect basic expectations, it will make the code hard to maintain as nobody would known that a circle has 2 centers including you in 3 months!
In a case like yours, it make make sense to add public accessors.
class potentialCircle
{
public:
unsigned int get_radius() const { return radius; }
....
};
That way, you can still make data private (or sometime protected) while having read only access to it. That way, you can write you comparison function as you wish. And in practice, if you have a class that represent a circle, you usually want at least being able to get basic properties like radius, aread, bounding rectangle by the way of a function.
Another thing is that public derivation as your (from potentialCircle) would only make senses if you have other classes that derives from it. However, if this is the case, then how would you compare the other kind of circles?
Notes:
With C++ 20, three way comparison would be even better.
I want to have a Collider interface class in which will have a overloaded -> operator to have access directy to the BoxCollider derived class. I want to have access to the members of box collider through the interface and chnage the type of collider at run-time.
So I thought of using templates:
template<typename T>
class ColliderV2 {
public:
virtual T* operator ->() = 0;
};
class BoxColliderV2 : public ColliderV2<BoxColliderV2> {
public:
float width;
float height;
BoxColliderV2* operator ->() {
return this;
}
};
int main()
{
ColliderV2<BoxColliderV2>* col = new BoxColliderV2;
(*col)->width = 1;
}
This works. But templates , as far as I know, will generate a brand new Collider class in compile-time filling T with Box Collider, correct? Thats why it worked. But later it prevents me from changing the collider type. I also thought of just making a virtual Collider class with Collider* operator->() ; overload in the derived class BoxCollider* operator->() ;
But if I tried :
Collider<BoxCollider>* col = new BoxCollider;
(*col)->width = 1; // won't work
doesn't work since Collider is not BoxCollider. And I don't want to dynamic_cast every possible collider type I could have. So, what can be done here?
As you've already found out, this doesn't work. Templates and runtime behavior are kind of contradicting mechanics. You can't create a common base class and let it act like a generic pointer to give you access to its derived types' members.
An interface specifies a contract against which you can code. You don't code against a specific implementation but the interface, so the interface has to provide all the members that you'd like to access. In your case this would result in width and height beeing part of ColliderV2 instead of BoxColliderV2. However this defeates the logic you are trying to mimic.
There are a few approaches that you can take:
Either make your collider type a variant, like
using ColliderType = std::variant<BoxColliderV2, MyOtherCollider, ...>;
and check for the actual type when you want to access the member
ColliderType myCollider = /* generate */;
if (auto boxCollider = std::get_if<BoxColliderV2>(&myCollider); boxCollider)
boxCollider->width = 0;
Or, keep the base class that you have, remove the operator-> and the template and do a dynamic cast on it:
ColliderV2* col = new BoxColliderV2;
if (auto boxCollider = dynamic_cast<BoxColliderV2*>(col); boxCollider)
boxCollider->width = 0;
You can also hide details like width or height behind more generic functions that are part of the interface. For example:
class ColliderV2 {
public:
virtual void setBounds(float width, float height) = 0;
};
class BoxColliderV2 : public ColliderV2 {
public:
void setBounds(float width, float height) override {
this->width = width;
this->height = height;
}
private:
float width;
float height;
};
int main()
{
ColliderV2* col = new BoxColliderV2;
col->setBounds(1, 1);
}
What you are trying to do is discouraged by C++. What you are trying to do is to change the type of something based on the return value of a function. The type system is designed to stop you from writing code like this.
One important restriction of a function is that can only return one type-of-thing. You can return one of a list of things if you wrap those possibilities in a class, and return that. In C++17, a ready-made class for this is std::variant. The restriction on this is that the list of things must be fixed (or a closed-set). If you want an arbitrary set of return values (open-set), you must use a different approach. You must restate your problem in terms a function that is done on the return value.
class BoxColliderV2 : public MyBaseCollider {
public:
void SetWidth(float new_width) override;
};
You may find this video useful. The bit of interest starts at around 40 minutes (but watch the whole video if you can). If you are interested in advice, I would suggest starting with std::variant, and if it works, move to virtual functions. Problems like collision detection get really complicated really quickly, and you will almost certainly require double dispatch at some stage. Start simple, because it's only going to get more complicated.
These excerpts from the ISO-Guidelines may help
1. When you change the semantic meaning of an operator, you make it
harder for other programmers to understand you code. guideline.
2. Dynamic casting is verbose and ugly, but deliberately so, because dynamic casting is dangerous, and should stand out. guideline
I think you are approaching the problem from the wrong direction. The purpose of an interface is that you don't have to know about the exact type or the implementation.
For example: You are using Axis-Aligned Bounding Boxes for collision detection. So, even if your CircleCollider uses a radius, you are still able to calculate its width and height from it. Now, you don't have to worry about if you are dealing with a BoxCollider or a CircleCollider, you have everything to make a Bounding Box.
class Collider
{
public:
virtual float x() const = 0;
virtual float y() const = 0;
virtual float width() const = 0;
virtual float height() const = 0;
};
class BoxCollider : public Collider
{
// Implementation...
};
class CircleCollider : public Collider
{
// Implementation...
};
Of course, you are maybe using something else, and not AABBs. I just wanted to demonstrate how you can use interfaces effectively.
I've been stuck on this problem and can't seem to get my head around it, I'm creating a program in C++ that calculates various functions such as area, perimeter, points of different shapes.
Part of this includes creating a leftTop variable of Point type (Point is a class that simply has 2 ints (x and y) and a method called Point to print out the x and y of different shapes). I've used a template to create a function of point type that simply returns x and y, I know this is incorrect but thought I'd try it anyway.
template <typename Point>
Point leftTop(Point x, Point y) {
return x, y;
}
But it needs to be a data member of point type (stored in a class called shape) that is used to store the x and y coordinates of the left top point of the shape and I'm stuck on how to implement this, as I need to use the leftTop variable to calculate the other points of the shape such as leftBottom, rightTop, etc.
You're making things over-complicated by using a templated function! The exact solution depends on how you have defined your Point class, but you probably just need a relevant constructor:
class Point
{
public
Point(int px, int py) : x{ px }, y{ py } {}
public: // Make these "private" if you want to prevent direct access
int x;
int y;
};
And then you can create your leftTop object very easily:
int left = 12; // Or whatever
int top = 17;
Point leftTop(left, top);
You can add other member functions to do pretty much anything else you'd care to.
As you're using Visual Studio, and thus may have access to the MFC classes, you could maybe take a look at how MFC implements its CPoint and CRect classes for guidance. If you can't get to see the MFC stuff, then the Windows.h file provides C-style structs called POINT and RECT that could also be helpful.
The following is an example:
In circle.h
class circle
{
double _radius;
public:
double getRadius() {return _radius;}
void setRadius(double r) {_radius=r;}
}
In main
int main()
{
circle a;
cout<<a.getRadius(); // I want to use "a.radius"
a.setRadius(3.2); // I want to use "a.radius=3.2"
}
So the first question is why we should use get and set function to access instance variables rather than directly access them? The second question is how to do operator overloading to let the function call of get and set looks concise(like what objective-c did)?
Of course, the simplest way to make the syntax that you're hoping for available is to just make _radius a public member called radius:
class circle
{
public:
double radius;
}
Now you can use it like so:
circle c;
c.radius = 10.0;
However, you shouldn't make such decisions based only on how you'd like to write code (or how you might write it in C#). I recommend that you think about the following points for every member:
Does it make sense to set the member directly? Perhaps the member is just a private part of the object's state and is affected by other member functions. Consider the following example, where the interface you really want to expose is just a function that increases the size of the circle:
class circle
{
public:
circle(double radius, double delta = 1.0)
: radius(radius), delta(delta) { }
double increaseSize() {
radius += delta;
return radius;
}
private:
double radius;
double delta;
}
Do you need to enforce an invariant? Consider, perhaps, that you have decided that there can be no such thing as a circle with a negative radius. You might want to enforce this by having a member function that checks the given new radius to make sure it is greater than 0.
Do you want to provide some different representation of the member through the interface? Maybe you want the circle to keep its radius as a member, but the only thing any clients will want to know is its area. You could make radius private and then provide a getArea function like so:
class circle
{
public:
circle(double radius)
: radius(radius) { }
double getArea() {
return PI * radius * radius;
}
private:
double radius;
}
It's possible that none of the above points apply at the moment, but may do at some point in the future. If you have this foresight, it might be best to provide getter and setter functions now. This ensures that the interface that clients use won't change later on.
As an alternative naming scheme for your getters and setters, it's quite common to simply have two overloaded functions - one for setting and one for getting - like so:
class circle
{
public:
void radius(double); // Set the radius
double radius(); // Get the radius
private:
double radius;
}
In answer to the first question: so your object is encapsulated and you can deal with changed internal representation or the need to modify/update when radius changes.
To the second: you can't. C++ does not support object getters and setters like that.
(It is actually just about possible, but it really isn't worth it)
There's various reasons to do this with setters and getters;
They provide better encapsulation; the actual values of a class' internal variables should be the responsibility of the class to set/get, not that of a user of an instance of a class. But there's different schools of thought on this subject.
They leave open the possibility of doing more than just setting/getting a value upon calling a setter/getter. For example,
class circle
{
double _radius;
double _perimeter;
public:
double getRadius() {return _radius;}
void setRadius(double r) {
_radius = r;
_perimeter = 2*M_PI*r;
}
};
Well, the way you indicate can be accomplshed simply by making radius a public variable :) However, consider this alternative approach:
class circle
{
private:
double _radius;
public:
const double &radius;
circle(double R)
: radius(R)
: radius(_radius)
{}
void setRadius(double r) {
_radius = r;
}
};
which would then be used like this:
cout << a.radius; // works
a.radius = 3.2; // produces error
a.setRadius(3.2); // works
This approach has the benefit of concise, possibly more intuitive getters (i.e., use the actual variable name), more concise code (no need for countless virtually empty getters), and possibly even increased performance (a call to a getter function is slower than directly accessing a variable, although this depends on compiler optimization settings).
There's benefits and drawbacks to all methods mentioned here. In the end, it's really all up to the preferences of your team/employer.
You use a getter and setter to achieve better encapsulation and to make it possible to change the underlying implementation in easier way.
About the second question: you can not do that. You will have to write a getter and setter method.
Well there is the initializer way:
OCD::OCD ( ) : _number( 0 )
{
}
and the in body constructor way:
OCD::OCD ( size_t initial_value )
{
_number = initial_value;
}
to access them inside the class instance just use the variable name:
_number = value;
but if you have an global, local or argument variable with the same name, you can be specific like this:
this->_number = value;
then from outside of the instance you can call it thus:
// (that is if _number was public)
std::cout << "ocd2._number => " << ocd2._number << std::endl;
std::cout << "ocd3p->_number => " << ocd3p->_number << std::endl;
same goes for methods:
std::cout << "ocd2.get( ) => " << ocd2.get() << std::endl;
std::cout << "ocd3p->get( ) => " << ocd3p->get() << std::endl;
see my gist on the subject: https://gist.github.com/LaughingSun/7d2330ccff0777bec106
Consider the following code:
class Rectangle
{
public:
// Constructors
Rectangle(){ init(0,0); }
Rectangle(int h, int w){ init(h,w); }
// Methods
void init(int h, int w)
{
_h = h;
_w = w;
}
// Getters / Setters
double get_h(void){ return _h; }
double get_w(void){ return _w; }
void set_h(double h){ _h = h; }
void set_w(double w){ _w = w; }
std::string get_name(void){ return _name; }
void set_name(std::string name){ _name = name; }
private:
// Private Members
int _h, _w;
std::string _name;
};
class House
{
public:
// <BEGIN PASSTHROUGHS>
std::string get_b_name(void){ return _base.get_name() };
std::string get_r_name(void){ return _roof.get_name() };
void set_b_name(std::string name){ _base.set_name(name); }
void set_r_name(std::string name){ _roof.set_name(name); }
// </END PASSTHROUGHS>
private:
// Private Members
Rectangle _base;
Triangle _roof;
};
This code works fine.
My question deals with the "passthrough" functions in the House class, enclosed by the PASSTHROUGHS tags. Is this the best way to do this? The arguments and return types will always match and there is no "intelligence" in these passthrough functions other than to make things cleaner and more straightforward.
My instinct would be something like one of the following:
get_b_name = _base.get_name;
// OR
std::string get_b_name(void) = _base.get_name;
... but neither seem to work unfortunately and it was only wishful thinking in the first place. If there are no easier options, telling me that is fine too. Thanks!
The problem, I think, is conceptual. Your design is quite un-object oriented in that the house does not represent an entity, but rather provides a bit of glue around the components. From that standpoint, it would make more sense to provide accessors to the elements, rather than pass-through functions:
class House {
Rectangle _base;
Triangle _roof;
public:
const Rectangle& base() const {
return _base;
}
const Triangle& roof() const {
return _roof;
}
};
I imagine that this is just a toy example, but the same reasoning applies: a class should represent an entity on which a set of operations are preformed, in some cases those operations might be implemented in terms of internal subobjects, but they are still operations on the type, and how they are gathered is an implementation detail.
Consider:
class House {
Thermostat t;
public:
int temperature() const {
return t.temperature();
}
};
From the user point of view the house has a temperature that can be read, and in this particular implementation, it is read from a thermostat that is a member. But that is an implementation detail. You might want to later install more thermostats in the house and substitute the single reading by an average of the readings, but that will not change the fact that the entity House (in this model) has a temperature.
That is, you should not be thinking in implementing pass-through functions, but rather on implementing features of the type. If the implementation happens to be a single forwarding to an internal method, that is fine.
But if the type contains internal members and it makes sense to access properties of the members, consider that it might be that you actual type should just provide access to its internal members. Consider that you want to move a piano inside the house, then you might just provide access to the door member and let the user check:
class House {
Door d;
public:
Door const & door() const {
return d;
}
};
bool can_enter_piano( House const & h, Piano const & p ) {
return h.door().width() > p.size();
}
There is no need to provide House::get_door_width(), and House::get_door_color() so that you can describe the entrance to a friend, and House::get_door_handle() so that they can know when they arrive...
That's possibly because your design is contradictory. Why on earth would you make a public member variable, then write a function that just forwards to one of that variable's functions? As a user of your class, I'd just call the function on the public variable myself. You're just confusing me by providing two ways to do the same thing. Or write getters and setters for a Rectangle class? That thing is just a bunch of variables, and doesn't need any getters and setters. You're not exactly going to inherit from it, and you can't really change the internal logic and maintain the same semantics, so it's very meaningless to not just make the variables public.
The Rectangle class needs a very healthy dose of YAGNI, and the House class just needs to look at itself again. The fact that there's no intelligence in the "passthrough" methods should be a huge alarm bell telling you that they are quite probably redundant and not helpful- especially since you can't change the public variables without breaking your interface anyway, it's not like the getters and setters are decreasing coupling or anything like that.
Methods should perform logic, or in the very least case, exist where logic might have to be done.