Calling constructors of certain classes based upon a common parameter c++ - c++

I'm currently working on class inheritance/polymorphism in my classes and I can't figure out this problem. Ok here it is: Let's say I have 2 mock classes, and I let the user choose a value that corresponds to the last parameter in the constructor:
class Planets {
private:
int x,y,z;
string a;
public:
Planets(string name, int diameter, int mass, int planet_kind) : a(name), x(diameter), y(mass), z(planet_kind) { }
Planets() { a="", x=0, y=0, z=0; }
//get and set functions to manipulate data
virtual void planet_creation(Planets& p1);
//function I want to modify depending on the planet
}
The thing to pay attention to is the planet_kind variable. I want the parent class to be a baseline for the others for example, gas giants would be 2, planets with life would be 1, etc... They would all have their own classes and constructors. For example in another class:
class Gas_giant : public Planets {
private:
int x,y,z;
string a;
public:
Gas_giant(string name, int diameter, int mass, int planet_kind) : a(name), x(diameter), y(mass), z(planet_kind) { }
Gas_giant() { a="Gas", x=0, y=0, z=2; }
//get and set functions to manipulate data
void planet_creation(Gas_giant& g);
//function I want to modify depending on the planet
//example: gas giants would be larger when created,have no solid mass,high gravity
}
basically I want the user to be able to input the kind of planet and the name, then depending on the kind they choose, call certain types of planets to be randomly generated in different ways. The functions aren't the problem, the issue I'm having is getting my program to choose different constructors based upon a parameter in a base constructor.
I don't want my program to create any "Type 0 " planets, it's just a class I'm trying to derive all the rest from.
Thanks in advance, and sorry if this is a dumb question.

There are languages in which a constructor can return a derived type, but C++ is not one of them. In C++ a constructor always constructs precisely its own type.
Anyway, it's not obvious that using a "planet_kind" integer is superior to using a different constructor. The different constructor option is likely to be quite a bit more readable:
Planet* henry = new GasGiant("Henry", ...);
Planet* bob = new Asteroid("Bob", ...);
...
If you really needed to use an enum for some reason (such as reading the data from a file), then you'll need a case statement:
for (;;) {
// read data into name, size, mass, kind
planets.emplace_back( make_planet(name, size, mass, kind) );
}
...
Planet* make_planet(std::string name, double radius, double mass, enum PlanetKind kind) {
switch (kind) {
case GIANT : return new GasGiant(name, radius, mass);
case ASTEROID: return new Asteroid(name, radius, mass);
// ...
default: // write an error message
}
}

Related

Inheritance and friend functions, accessing protected members from base class

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.

Variable to Point to a Vector

I'm attempting to make a command line side scrolling shooter. However, I am struggling to get the inheritance and class/struct structure set up for the different ship types. However, there is a fair chance that I am completely misunderstanding how to go about this.
class Ship
{
int health;
float charging;
bool charged;
coords location;
bool shielded;
int chargeSpeed;
int cannons;
int shieldHealth;
struct enemyShip
{
int speed;
shipType type;
};
struct bossShip
{
int Bonuspoints;
};
struct myShip
{
int lives;
int points;
int isDead;
};
void createShip(shipType type, int speed, int health, bool shields, int cannons, int chargeSpeed, int bonusPoints)
{
switch (type)
{
speeder:
Ship::enemyShip newShip;
newShip.speed = 0;
ships.push_back(newShip);
bruiser:
sprayer:
boss:
}
}
};
That's theShip class as it stands currently. My idea was that I will be able to pass the parameters to the createShip method (from my gameloop) and that will create a new Ship of the correct type and then dump it into the list of ships (which is global).
However, whilst I can easily access the attributes of my newShip object that belong to whichever struct has been used to create it, in the case shown I can use newShip.speed after newShip = Ship::enemyShip newShip; to access these. However, I cannot work out how to access all of the attributes that it will have inherited from the parent class; such as health, charging, etc.
Any help would be appreciated, I have searched, however, most answers simply say this->x = x::x or something of that ilk, and I have tried newShip->health = 100 and that doesn't work. Consequently, either a little more detail would be appreciated or a completely different answer.
Thanks in advance!
You need to hoist (for example) enemyShip out of Ship and declare it as:
struct enemyShip : Ship
{
int speed;
shipType type;
};
The : Ship says that enemyShip derives from Ship.
You will then need to define createShip outside struct Ship (because inside Ship enemyShip won't be properly defined).

Prevent breaking encapsulation

I have this class:
class Phone {
private:
string producer, color;
int weight, dimension;
public:
Phone(string &producer, string &color, int &weight, int &dimension):
producer(producer), color(color), weight(weight), dimension(dimension) {};
Phone():
producer(""), color(""), weight(0), dimension(0) {};
virtual ~Phone() {};
string getProducer(void) const;
string getColor(void) const;
int getWeight(void) const;
int getDimension(void) const;
virtual void displayInfo(void) const;
};
The problem is here caused by the fact that I expose the internal implementation of the object via getters.
But how can I prevent this?
Because usually in my code, I need to know some private data from my object (for comparision is one example), and that's why I use getters.
So then I rewrite the class to something like this:
class Phone {
private:
string producer, color;
int weight, dimension;
public:
Phone(string &producer, string &color, int &weight, int &dimension):
producer(producer), color(color), weight(weight), dimension(dimension) {};
Phone():
producer(""), color(""), weight(0), dimension(0) {};
virtual ~Phone() {};
bool isTheProducer(string& producer) const { return this->producer == producer };
bool hasWeight(int& weight) const { return this->weight == weight };
bool hasDimension(int& dimension) const { return this->dimension == dimension };
virtual void displayInfo(void) const;
};
Is this a better design (by the fact that I don't get the actual private value)?
As you might have seen from the other answers and comments, the answer is: It depends.
In fact, it depends mainly on the usecases where your class is used. Let's stick first to the example given in the question, the comparison of objects. Since it is not clearly visible from the question if we want to compare two phone objects or just a specific data member I will discuss both situations here.
Comparing a data member to out-of-class data
Let's take this usecase where we search for all phones with a weight bigger than x(just pseudocode):
for (Phone& p in phoneList) {
if (p.getWeight() > x) {
cout << "Found";
}
}
Then the first class example is perfectly fine, since this is not an intrinsic feature of the phone, and thus the phone class is not responsible for handling it. In addition, the result does not expose more than absolutely required for the task.
Comparing two phone objects
In this case both code examples are equally good (or in this case equally bad). In both cases the user has to know a lot of details about how phones are represented to compare all necessary members. If in a later revision a new member is added to the class, every code segment that compares two phones has to be adapted. To overcome this, one can add a function to the class that does exactly the comparison.
class Phone {
private:
string producer, color;
int weight, dimension;
public:
bool IsEqualTo(const Phone& other)
{
return (producer == other.producer && color == other.color &&....);
}
Non comparitive usecase
But let's go to a more advanced example. Let's assume the following task: A user enters the pin to a phone and if it is the correct one, the phone should unlock. Let's assume a very naive approach:
class Phone
{
private:
int pin;
bool unlocked;
public:
int getPin() { return pin; }
void unlock() { unlocked = true; }
};
and the corresponding call
if (phone.getPin() == enteredPin)
phone.unlock();
In this case we have a totally different situation. Here we need to consider the "tell, don't ask" rule, which basically says that it is a bad design to query the state of an object first, make a decision and then tell the object what to do. Instead we should only tell the object what we want, and let it do the work for us. In this usecase this is obvious, since unlocking the phone only when the pin is correct is a responsibility of the phone, not of the user that uses the phone class. But in more complex scenarious many programmers will do exactly what I described here.
Back to the problem: A good solution here would be for example
class Phone
{
private:
int pin;
bool unlocked;
public:
void CheckPin(int enteredPin) {
if (pin == enteredPin)
unlocked = true;
}
};
with the code
phone.CheckPin(enteredPin);
Hope this helps, and thanks to #KonradRudolph for pointing to the "tell, don't ask rule". Feel free to help me to improve the answer per commenting on it :)
The first one, even with getter, is encapsulated. Consider the color() method, which returns a string. Even if you change the implementation of Phone such that you store the color as an enum rather than a string, your method can still return a string if you do some sort of conversion first. The important part is that you can change the implementation of color() and the underlying storage without users of the class needing to change.
Compare to a class that stores color as a publicly accessible string. If you later change the data member to an enum, you need to modify every location that uses the color. This is less of a property of encapsulation and more a property of separating interface from implementation.
Encapsulation allows controlling of attributes exclusively via methods within the class. Both examples are encapsulated.

How to access instance variables in C++ like Objective-C getter and setter

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

Best way to alias methods of member object? "Passthrough methods"

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.