I am trying to comprehend virtual functions. How so I make my put() function virtual? What changes does that necessitate in the code?
#include <iostream>
#include <string>
using namespace std;
class Circle
{
public:
Circle(double radius) {this->radius = radius; }
void put() const {cout << "Radius = " << radius;}
private:
double radius;
};
class ColoredCircle: public Circle
{
public:
ColoredCircle(double radius, string color);
void put() const;
private:
string color;
};
ColoredCircle::ColoredCircle(double radius, string color)
: Circle(radius), color(color) {}
void ColoredCircle::put() const
{
Circle::put();
cout << " Color = " << color;
}
int main()
{
ColoredCircle redCircle(100., "red");
Circle* circle1 = &redCircle;
circle1->put();
cout << endl;
Circle circle(50.);
Circle* circle2 = &circle;
circle2->put();
cout << endl;
std::cin.get();
return 0;
}
You just have to write the virtual keyword in front of the function in the base class :
class Circle
{
public:
Circle(double radius) {this->radius = radius; }
virtual void put() const {cout << "Radius = " << radius;}
// ^^^^^^^
private:
double radius;
};
But you should understand the case where the virtual functions are used. What is the performances cost, why it is useful, etc ...
A little piece of answer : A virtual method is a special of method whose the behavior can be overriden within an inheriting class with amethod of the same signature.
About the performance cost : There is definitely measurable overhead when calling a virtual function - the call must use the vtable to resolve the address of the function for that type of object. The extra instructions are the least of your worries. Not only do vtables prevent many potential compiler optimizations, they can also thrash your I-Cache.
Of course whether these penalties are significant or not depends on your application, how often those code paths are executed, and your inheritance patterns.
I would suggest you to read some articles about virtual functions, here is a non exhaustive list :
http://www.cplusplus.com/doc/tutorial/polymorphism/
http://en.wikipedia.org/wiki/Virtual_function
http://www.learncpp.com/cpp-tutorial/122-virtual-functions/
What is the performance cost of having a virtual method in a C++ class?
Related
So I saw this thread: What does it mean to "program to an interface"?. Which talks about declaring a Parent, but initializing it as a Child. Is it possible to do the same but with c++? For example: I have an interface Shape which can be implemented as Triangle or Square.
I tried to do the following but my program didn't compile:
Shape * myShape = new Square();
myShape->uniquetoSquare();
"typeinfo for Shape", referenced from:
typeinfo for Triangle in Triangle.o
class Shape {
public:
Shape(){};
int height;
int width;
string color;
void sayHello(){
cout << "Hello!";
}
int getArea(){
return 0;
}
}
class Triangle: public Shape {
public:
bool obtuse;
Triangle(){
obtuse = false;
};
void sayHello(){
cout << "Hello I'm a triangle!";
}
int getArea(){
return height*width / 2;
}
}
class Square: public Shape {
public:
bool rectangular
Square(){
rectangle = true;
};
void sayHello(){
cout << "Hello I'm a square!";
}
int getArea(){
return height*width;
}
void uniqueToSquare(){
cout << "This func is only in square!";
}
}
Shape does not have a function named uniqueToSquare. Remember that if you are using a Shape, then you can only use shape-like methods.
If you want to use it as a Square, then do something like:
Square* mySquare = dynamic_cast<Square*>(myShape);
if (mySquare != nullptr) mySquare->uniqueToSquare();
This is a simple polymorphism example. Yes it is possible in C++ and is actually the heart of the benefits of Object-Oriented design
With C++ it isn't as simple as you might hope. You need virtual functions to do what you want. Modifying your example to be "good" C++.
class Shape {
public:
Shape(){}
int height;
int width;
string color;
virtual void sayHello() const {
cout << "Hello!";
}
virtual int getArea() const {
return 0;
}
//virtual destructor, no need to declare this on the derived types
virtual ~Shape() {}
}
class Triangle : public Shape {
public:
bool obtuse;
Triangle() {
obtuse = false;
}
void sayHello() const {
cout << "Hello I'm a triangle!";
}
int getArea() const {
return height*width / 2;
}
}
class Rectangle : public Shape {
public:
bool square;
Rectangle() {
square = false;
}
void sayHello() const {
cout << "Hello I'm a rectangle!";
}
int getArea() const {
return height*width;
}
void uniqueToRectangle() const {
cout << "This func is only in rectangle!";
}
}
The error your getting seems to be because of missing runtime type information RTTI. You may want to enable this but it really is unnecessary for what you want to achieve. Use dynamic cast as others have suggested (which also uses RTTI).
Shape* myShape = new Rectangle();
((Rectangle*)myShape)->uniquetoRectangle();
This is OK but remember to delete myShape; before it goes out of scope. See RAII for the use of destructors for that.
Your variable myShape is a pointer to a Shape. Your class Shape does not have a method called uniqueToSquare(). Therefore, you have an error.
The solution is to initialise myShape as a Square simply by Square myShape = Square();
Remember that it is always better to preserve the real type of an object, this is better for performance, and basically gives more information to the compiler. You only resort to dynamic polymorphism when you really have to (ie, storing polymorphic objects in an array).
I'm learning about c++ polymorphism. In the code below, a pointer called shape of the type of the base class Shape is creates and then pointed at the objects r and c.
The functions printArea(r); and printArea(c); are then called. However, at the point that these functions are called shape is pointing to the address of c. So how does it work when you call printArea(r);?
#include<iostream>
using namespace std;
class Shape {
public:
virtual float getArea() const = 0;
};
class Rectangle : public Shape {
private:
float width;
float height;
public:
Rectangle(float width, float height) : width(width), height(height) {}
float getArea() const {return width * height;}
};
class Circle : public Shape {
private:
float radius;
public:
Circle(float radius) : radius(radius) {}
float getArea() const {return 3.14159f * radius *radius;}
};
void printArea(const Shape& shape) {
std::cout << "Area: " << shape.getArea() << std::endl;
}
int main() {
Rectangle r(2,6);
Shape* shape = &r;
Circle c(6);
shape = &c;
printArea(r);
printArea(c);
printArea(*shape);
return 0;
}
I would guess your question is how, technically, is the call to getArea dispatched at run time.
The C++ standard does not prescribe this. It prescribes exactly which implementation must be executed, but not how that is accomplished.
Nearly all extant C++ implementations do that by placing a hidden pointer in each object of class with one or more virtual functions. That hidden pointer points to a table of function pointers, namely pointers to the virtual methods of the class of the object's dynamic type. This is called a vtable. And in general the call is dispatched by checking the object's vtable pointer, and retrieving the function pointer from the getArea item in the vtable, and calling that function.
There are complications for multiple inheritance, but those are just that: complications.
An alternative could be to search up the base class chain for each call.
That would be less efficient but still it's been used, at least in other languages, e.g. in original Smalltalk, and in Borlands GUI class framework for Pascal in Windows in the 1990s.
Another alternative is to place pointers to each virtual function directly in each object, essentially a vtable in each object. That approach is sometimes used in C. The main advantage is that it's conceptually simple. It also avoids one indirection. But it wastes space and doesn't generalize very well.
#include<iostream>
using namespace std;
class Shape {
public:
virtual float getArea() const = 0;
};
class Rectangle : public Shape {
private:
float width;
float height;
public:
Rectangle(float width, float height) : width(width), height(height) {}
float getArea() const {return width * height;}
};
class Circle : public Shape {
private:
float radius;
public:
Circle(float radius) : radius(radius) {}
float getArea() const {return 3.14159f * radius *radius;}
};
void printArea(const Shape& shape) {
std::cout << "Area: " << shape.getArea() << std::endl;
}
int main() {
Rectangle r(2,6);
Shape* shape = &r; // shape stores the address of object r which when further call
std::cout<< shape <<endl; //called sends its address
Circle c(6);
shape = &c; // same as r is being processed
std::cout<<shape<<endl;
printArea(r); // same thing is taking place here reference is passed and then polymorphism come
printArea(c); // into play
printArea(*shape); // as the shape was given reference of c in the end it returns its value
return 0;
}
if u still have any questions feel free to ask in comments!
In this code I've started working on, I came across a common pattern that somehow doesn't sit right with me. Usually, it involves an enum, a map, a switch and some sort of class hierarchy. I've tried to abstract a MWE:
#include <iostream>
#include <map>
class Shape {
public:
virtual double SumOfInternalAngles() { throw std::exception(); }
};
class Triangle : public Shape {
public:
double SumOfInternalAngles() { return 180.0; }
};
class Rectangle : public Shape {
public:
double SumOfInternalAngles() { return 360.0; }
};
enum TeamShapes {AlicesTriangle, BobsRectangle, CarolsTriangle};
int main()
{
Triangle alicesTriangle;
Rectangle bobsRectangle;
Triangle carolsTriangle;
std::map<TeamShapes, Shape*> shapeMap;
shapeMap[TeamShapes::AlicesTriangle] = &alicesTriangle;
shapeMap[TeamShapes::BobsRectangle] = &bobsRectangle;
shapeMap[TeamShapes::CarolsTriangle] = &carolsTriangle;
for(auto it : shapeMap)
{
switch (it.first)
{
case TeamShapes::AlicesTriangle:
std::cout << it.second->SumOfInternalAngles() << std::endl;
break;
case TeamShapes::BobsRectangle:
std::cout << static_cast<Rectangle*>(it.second)->SumOfInternalAngles() << std::endl;
break;
}
}
return 0;
}
There seems to be repetitive information, and both versions of accessing the member function have drawbacks: In the first case, you need to have a virtual member function in the base class, which means that all the derived classes get "cluttered" with functions that don't really make sense for them, e.g. a Circle would end up with a function getCorners(). In the second case I would prefer not needing the cast, although I know that it is necessary. Maybe someone can point me in a direction where I can come up with a better design for this case.
I'm quite new to C++, so I'd like to hear what the "best practices" and "conventions" regarding such constructs are. Maybe the code is fine, and I simply need to adjust?
If you make your base class pure virtual (i.e make the class abstract), then you don't have to implement SumOfInternalAngles() in it and thus no need to throw an exception. Shape then becomes an abstract interface to be implemented by a derived class and this derived class MUST implement SumOfInternalAngles().
Then in your switch statement, you don't need to cast unless you wanted to call a method specific to the derived class such as getCorners() which may or may not be present in all derived versions of Shape.
To do this simply change you shape definition to
class Shape {
public:
virtual double SumOfInternalAngles() = 0;
};
And use the first version of your switch case.
i.e
case TeamShapes::AlicesTriangle:
std::cout << it.second->SumOfInternalAngles() << std::endl;
break;
case TeamShapes::BobsRectangle:
std::cout << it.second->SumOfInternalAngles() << std::endl;
break;
EDIT: some sample code to try and help illustrate.
#include <iostream>
#include <string>
class base
{
public:
virtual std::string AMethodThatMustBeImplemented() = 0;
virtual std::string ABaseMethod() { return std::string("base::ABaseMethod"); }
};
class A : public base
{
public:
virtual std::string AMethodThatMustBeImplemented() { return std::string("A::AMethodThatMustBeImplmented"); }
// No need to implment ABaseMethod here unless we wanted to!
};
class B : public base
{
public:
virtual std::string AMethodThatMustBeImplemented() { return std::string("B::AMethodThatMustBeImplmented"); }
virtual std::string ABaseMethod() { return std::string("B::ABaseMethod"); }
};
int main(int argc, char** argv)
{
//base obj; // can't do this since base has 'pure virtual' called AMethodThatMustBeImplemented.
A objA;
B objB;
std::cout << objA.AMethodThatMustBeImplemented() << '\n';
std::cout << objA.ABaseMethod() << '\n';
std::cout << objB.AMethodThatMustBeImplemented() << '\n';
std::cout << objB.ABaseMethod() << '\n';
base& b = static_cast<base&>(objB);
std::cout << b.ABaseMethod() << " <- notice still calling B::ABaseMethod\n";
std::cout << b.base::ABaseMethod() << " <- ah-ha now calling base::ABaseMethod\n";
}
Maybe what you want is an intermediate interface for your derived class, in this case a "Polygon" interface derived from "Shape", which has methods that make sense for polygons, but not for a circle for example :
#include <iostream>
#include <map>
#include <math.h>
class IShape {
public:
virtual double getArea() = 0;
};
class IPolygon : public IShape {
public:
virtual double sumOfInternalAngles() = 0;
};
class Triangle : public IPolygon {
public:
Triangle(double _base, double _height) : base(_base), height(_height) {}
double sumOfInternalAngles() { return 180.0; }
double getArea() { return (base * height)/2; }
private:
double base;
double height;
};
class Rectangle : public IPolygon {
public:
Rectangle(double _width, double _height) : width(_width), height(_height) {}
double sumOfInternalAngles() { return 360.0; }
double getArea() { return (width * height); }
public:
double width;
double height;
};
class Circle : public IShape {
public:
Circle(double _radius) : radius(_radius) {}
double getArea() { return (3.14 * pow(radius,3)); }
public:
double radius;
};
enum TeamShapes {AlicesTriangle, BobsRectangle, CarolsCircle};
int main()
{
Triangle alicesTriangle(10,10);
Rectangle bobsRectangle(10,10);
Circle carolsCircle(10);
std::map<TeamShapes, IShape*> shapeMap;
shapeMap[TeamShapes::AlicesTriangle] = &alicesTriangle;
shapeMap[TeamShapes::BobsRectangle] = &bobsRectangle;
shapeMap[TeamShapes::CarolsCircle] = &carolsCircle;
for(const auto& it : shapeMap)
{
switch (it.first)
{
case TeamShapes::AlicesTriangle:
case TeamShapes::BobsRectangle:
std::cout << static_cast<IPolygon*>(it.second)->sumOfInternalAngles() << std::endl;
std::cout << it.second->getArea() << std::endl;
break;
case TeamShapes::CarolsCircle:
std::cout << it.second->getArea() << std::endl;
break;
}
}
return 0;
}
You still have to cast your pointer, but I find it preferable to a non virtual method which throw an exception.
In C++, I have two separate base classes, each of whose derived classes are somewhat coupled. Here's an example for the kind of thing I'd like to do:
First define a set of classes, e.g.,:
class Shape
{
public:
double area;
double diameter;
};
class Rectangle : public Shape
{
public:
double width;
double height;
};
class Circle : public Shape
{
public:
double radius;
};
The second set of classes then pertains to operations being performed on this first set of classes, something like this:
class Calculator
{
public:
static Calculator *create_calculator(shape *shape,const char *shape_type); // the factory
virtual void calculate()=0; // the actual calculation
};
class area_circles : public Calculator
{
class circles *circle;
public
area_circles(circles *circle)
{
this->circle = circle;
}
void calculate()
{
this->area = PI*pow(circle->radius,2);
}
}
class area_rectangles : public Calculator
{
class rectangles *rectangle;
public
area_rectangles(rectangles *rectangle)
{
this->rectangle = rectangle;
}
double calculate()
{
this->area = rectangle->height * rectangle->width;
}
}
Calculator *Calculator::create_calculator(shape *shape, const char *shape_type)
{
if (shape_type=="circle")
return new area_circles(shape);
if (shape_type=="rectangle")
return new area_rectangles(shape);
}
Then, the idea would be to call all this using something like:
rectangles *my_rectangle;
Calculator *area_calculator;
area_calculator = area_calculator->create_calculator(my_rectangle, "rectangle");
area_calculator->calculate();
However, this doesn't compile and I get an error (quite sensibly) pointing out how the Shape class has no member "width", and that "a value of type "shape *" cannot be assigned an entity of type "rectangles". The error's pretty clear on why this code isn't working.
Would anyone know how to get the code here to do what I'm trying to do?
From a design perspective, I recognize that part of the problem is that the derived classes end up being coupled, so maybe there is a better way to try to decouple the calculator class from the shape class. But I'd like to at least try out this approach for a while as well in my implementation, and for that I need the code to compile.
I am not entirely sure what you are trying to achieve here but I think the more usual approach to it is something like this:
class Shape
{
public:
virtual ~Shape() {}
// concrete classes must implement this function
virtual double get_area() const = 0;
};
class Circle
: public Shape
{
double diameter;
public:
Circle(double diameter): diameter(diameter) {}
virtual double get_area() const
{
return M_PI * diameter * diameter / 4;
}
};
class Rectangle
: public Shape
{
double width;
double height;
public:
Rectangle(double width, double height): width(width), height(height) {}
virtual double get_area() const
{
return width * height;
}
};
int main()
{
Circle c(2);
Rectangle r(20, 40);
// use Shape references (or pointers) to invoke polymorphic behaviour
Shape& cs = c;
Shape& rs = r;
std::cout << "Area of circle : " << cs.get_area() << '\n';
std::cout << "Area of rectangle: " << rs.get_area() << '\n';
}
I'm trying to redefine two member functions from their parent's definition.I don't know if I have it right or not, but something in my code has errors attached and I can't find out what.
some of the header:
class Account
{
public:
Account(double);
void creditBalance(double);
void debitBalance(double);
double getBalance() const;
protected:
double balance;
};
class CheckingAccount : public Account
{
public:
CheckingAccount(double, double);
void feeCreditBalance(double);
void feeDebitBalance(double);
private:
double fee = 10;
};
relevant cpp file part:
void Account::creditBalance(double plus)
{
if(plus > 0)
balance += plus;
else
cout << "Cannot credit negative.";
}
void Account::debitBalance(double minus)
{
if(minus <= balance)
balance -= minus;
else
cout << "Debit amount exceeded account balance.";
}
void CheckingAccount::feeCreditBalance(double plus)
{
if(plus > 0){
balance += plus;
balance -= fee;
}
else
cout << "Cannot credit negative.";
}
void CheckingAccount::feeDebitBalance(double minus)
{
if(minus <= balance){
balance -= minus;
balance -= fee;
}
else
cout << "Debit amount exceeded account balance.";
}
UPDATE:
I added this:
class Account
{
public:
Account(double);
virtual void creditBalance(double);
virtual void debitBalance(double);
double getBalance() const;
protected:
double balance;
};
Now I get error: virtual outside class declaration
I could use an example of how to properly initialize fee correctly.
EDIT 2:
I have tried changing the constructor line to this:
CheckingAccount::CheckingAccount(double initBal, double phi) : Account(initBal), fee(phi)
{
if(initBal < 0)
initBal = 0;
balance = initBal;
cerr << "Initial balance was invalid.";
if(phi < 0)
phi = 0;
fee = phi;
}
not working, I'm going to work around with changing syntax on the fee(phi) part. I don't know if anyone will respond to this.
You can not initialise member variables in place(double fee = 10) like that. You have to initialise then in the initiasation list in the derived class constructor. Also note that if you are using inheritance you should make base class destructor virtual.
If the intention is that for instances of CheckingAccount accounts the versions which use a fee is called, then you want to use virtual methods.
A virtual method is a method decalared (at least in the base class) as "virtual", and has the same name and signiture in any derived classes. When a virtual method is called, it will call the "most derived" version for the instance.
To do this just declare "void creditBalance(double);" and "void debitBalance(double);" virtual (ie "virtual void creditBalance(double);" and "virtual void debitBalance(double);". Then in CheckingAccount rename "feeCreditBalance" and "feeDebitBalance" to "creditBalance" and "debitBalance".
EDIT: Simple example.
Header
class Base
{
public:
Base(int x);
//declare virtual so that derived classes may overide it
virtual void sayHello();
protected:
int x;
};
class Derived : public Base
{
public:
Derived(int x, int y);
//overide Base::sayHello(). the virtual keyword here is optional.
virtual void sayHello();
protected:
int y;
};
Cpp
Base::Base(int x)
:x(x)
{}
Derived::Devired(int x, int y)
:Base(x), y(y)
{}
void Base::sayHello()
{
std::cout << "Hello from Base!" << std::endl;
std::cout << "X = " << x << std::endl;
}
void Derived::sayHello()
{
std::cout << "Hello from Derived!" << std::endl;
std::cout << "X = " << x << " Y = " << y << std::endl;
}
int main()
{
Base a(5);
a.sayHello();//"Hello from Base!..."
Derived b(10, -20);
b.sayHello();//"Hello from Derived!..."
Base *c = &b;//take pointer to b, reference would also do
c->sayHello();//"Hello from Derived!..." because its a Derived instance, eventhough its a Base variable.
}
You can then derive from Derive again (class DerivedAgain : public Derived) and also overload the functions again.
You can also derive multiple subclasses from Base, which can each have their own overrides for the virtual methods, just like I did for the Derived class.
EDIT2: Added variables to example and how to use initialiser list to initialise the base class and member variables.
When you want to override a method in the parent class, you should give the method the same name. Don't call it feeCreditBalance if you want it to override creditBalance. Also, you need to use the "virtual" keyword in the definition of the parent class's method if you want a call to creditBalance to always use the one from the child class.
You need to learn overriding the member function ( using virtual keyword) . IF you want to change the base class member function implementation then you need to override those methods and provide different implementation in derived classes.
EDIT:
double fee = 10;
This may be the error which you are talking. Use member initializer list to initialize fee. You cannot initialize fee as in-class constant.
I think fee should be static const if it remains constant and does not vary for each object.
Declare in the class like this:
static const double fee;
Define outside class like this:
const double ClassName::fee = 10;
And if you want your implementation should not allow -Ve balance than something like this and also you should make use of virtual functions in inheritance which is better approach:
void CheckingAccount::feeCreditBalance(double plus)
{
if(plus - fee > 0)
balance += (plus - fee);
else
cout << "Cannot credit negative.";
}