I'm confused...it seems that both things do the same thing.
In this first code, I believe that the derived classes are hiding the function names of the base classes.
#include <iostream>
using namespace std;
class Quadrilateral {
public:
void greeting() {
std::cout << "i am a quadrilateral" << std::endl;
}
};
class Square : public Quadrilateral {
public:
void greeting() {
std::cout << "i am a square" << std::endl;
}
};
class Trapezoid : public Quadrilateral {
public:
void greeting() { //hides greeting from quadrilateral function
std::cout << "Hi I'm a Trapezoid" << std::endl;
}
};
int main()
{
Trapezoid tz;
tz.greeting();
}
This seems to have the same exact result: [here they are being overriden because it is virtual in the base class]
#include <iostream>
using namespace std;
class Quadrilateral {
public:
virtual void greeting() {
std::cout << "i am a quadrilateral" << std::endl;
}
};
class Square : public Quadrilateral {
public:
void greeting() {
std::cout << "i am a square" << std::endl;
}
};
class Trapezoid : public Quadrilateral {
public:
void greeting() { //hides greeting from quadrilateral function
std::cout << "Hi I'm a Trapezoid" << std::endl;
}
};
int main()
{
Trapezoid tz;
tz.greeting();
}
So I guess I'm just really confused as to...what is the difference? Or what is the point of making it virtual in the base class if it's just gonna have the same effect in this situation?
Virtual functions are used to call the overriden function from the base class pointer.
With your second example you can get the same result if you do the following in the main()
Trapezoid tz;
Quadrilateral *base = &tz;
base->greeting(); // it will print "Hi I'm a Trapezoid"
And this is the difference with the first example: possibility to call derived function from the base class pointer.
If you not override the virtual base function in the derived class, then the base virtual function will be called.
Usage example.
Imagine, that you want to create many objects with the base class Quadrilateral (for example five squares and three trapezoids):
Square sq1, sq2, sq3, sq4, sq5;
Trapezoid tz1, tz2, tz3;
Now, at some point in your code you want to go throw all of this objects and call the abstract function (in your case greeting()). So, with help of virtual function you can do it very simple: put all objects in an array of pointers and call the propper function. Here is how:
Quadrilateral *base[8] = {&sq1, &sq2, &sq3, &sq4, &sq5, &tz1, &tz2, &tz3};
for (int i = 0; i < 8; i++) {
base[i]->greeting();
}
In the output you will recieve five times "i am a square" and three times "Hi I'm a Trapezoid".
It comes vary helpfully when you create all different shapes (for example with different dimensions, properties) and want to go throw all of this objects and call, for example, calc() function to make an calculation individualy for each shape.
I hope this helps you.
In C++, if you declare/have a struct or class variable like in this example, the compiler trivially knows its type and always calls the correct function, irrespective of virtual/not.
Virtual functions only matter when dealing with pointers or references.
Try adding this after you existing code, before the end of main:
Quadrliateral *q = &t;
q->greeting();
And you will find it matters a lot whether all the greetings functions are virtual or not.
First of all, format your code please!
First example
class Quadrilateral {
public:
void greeting() {
std::cout << "i am a quadrilateral" << std::endl;
}
};
class Square : public Quadrilateral {
void greeting() {
std::cout << "i am a square" << std::endl;
}
};
class Trapezoid : public Quadrilateral {
public:
void greeting() { //hides greeting from quadrilateral function
std::cout << "Hi I'm a Trapezoid" << std::endl;
}
};
int main() {
Trapezoid tz;
tz.greeting();
}
In this example is totally normal that Trapezoid.greeting() hides Quadrilateral.greeting(): it's an overriding (same method name, same return, same parameters (none)).
Second example
class Quadrilateral {
public:
virtual void greeting() {
std::cout << "i am a quadrilateral" << std::endl;
}
};
class Square : public Quadrilateral {
void greeting() {
std::cout << "i am a square" << std::endl;
}
};
class Trapezoid : public Quadrilateral {
public:
void greeting() { //hides greeting from quadrilateral function
std::cout << "Hi I'm a Trapezoid" << std::endl;
}
};
int main() {
Trapezoid tz;
tz.greeting();
}
The same. You create an objcet of static-type Trapezoid that have dynamic-type Trapezoid. So tz.greeting will print "I'm a trapezoid" because greeting() is an override.
Third example
class Shape {
public:
virtual void greeting() {
std::cout << "Shape" << std::endl;
}
};
class Square : public Shape {
/* override method greeting() of Shape class */
void greeting() {
std::cout << "Square" << std::endl;
}
};
class Triangle : public Shape {
public:
/* override method greeting() of Shape class */
void greeting() {
std::cout << "Triangle" << std::endl;
}
};
int main() {
Shape* shape = new Triangle();
shape->greeting(); /* prints "Triangle" */
shape = new Square();
shape->greeting(); /* prints "Square" */
}
Related
I have class Set which consists of dynamically allocated IShape where IShape is inherited by Square, Rectangle etc. and I need to make filter function to create new set of only certain type (E.g. Squares). Basically to go through existing set and pick only shape which is defined somehow (through parameters?) and create new set of that shape. How could this be done?
To avoid using dynamic_cast, have your IShape class declare a pure virtual function called (say) GetTypeOfShape. Then override that in each of your derived classes to return the type of shape that each represents (as an enum, say). Then you can test that in your filter function and proceed accordingly.
Example code:
#include <iostream>
class IShape
{
public:
enum class TypeOfShape { Square, Rectangle /* ... */ };
public:
virtual TypeOfShape GetTypeOfShape () = 0;
};
class Square : public IShape
{
public:
TypeOfShape GetTypeOfShape () override { return TypeOfShape::Square; }
};
class Rectangle : public IShape
{
public:
TypeOfShape GetTypeOfShape () override { return TypeOfShape::Rectangle; }
};
// ...
int main ()
{
Square s;
Rectangle r;
std::cout << "Type of s is: " << (int) s.GetTypeOfShape () << "\n";
std::cout << "Type of r is: " << (int) r.GetTypeOfShape () << "\n";
}
Output:
Type of s is: 0
Type of r is: 1
Live demo
I'm using multiple inheritance in C++ and extending base methods by calling their base explicitly. Assume the following hierarchy:
Creature
/ \
Swimmer Flier
\ /
Duck
Which corresponds to
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Flier::print();
Swimmer::print();
std::cout << "I'm a duck" << std::endl;
}
};
Now this presents a problem - calling the duck's print method calls its respective base methods, all of which in turn call the Creature::print() method, so it ends up being called twice-
I'm a creature
I can fly
I'm a creature
I can swim
I'm a duck
I would like to find a way to make sure the base method is called only once. Something similar to the way virtual inheritance works (calling the base constructor on the first call, then only assigning a pointer to it on successive calls from other derived classes).
Is there some built-in way to do this or do we need to resort to implementing one ourselves?
If so, how would you approach this?
The question isn't specific to printing. I wondered if there's a mechanism for extending base methods and functionality while keeping the call order and avoiding the diamond problem.
I understand now that the most prominent solution would be to add helper methods, but I just wondered if there's a "cleaner" way.
Most likely this is a XY problem. But ... just don't call it twice.
#include <iostream>
class Creature
{
public:
virtual void identify()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a swimmer\n";
}
virtual void tell_ability()
{
std::cout << "I can swim\n";
}
};
class Flier : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a flier\n";
}
virtual void tell_ability()
{
std::cout << "I can fly\n";
}
};
class Duck : public Flier, public Swimmer
{
public:
virtual void tell_ability() override
{
Flier::tell_ability();
Swimmer::tell_ability();
}
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a duck\n";
}
};
int main()
{
Creature c;
c.identify();
std::cout << "------------------\n";
Swimmer s;
s.identify();
std::cout << "------------------\n";
Flier f;
f.identify();
std::cout << "------------------\n";
Duck d;
d.identify();
std::cout << "------------------\n";
}
Output:
I'm a creature
------------------
I'm a creature
I can swim
I'm a swimmer
------------------
I'm a creature
I can fly
I'm a flier
------------------
I'm a creature
I can fly
I can swim
I'm a duck
------------------
We can let the base class keep track of the attributes:
#include <iostream>
#include <string>
#include <vector>
using namespace std::string_literals;
class Creature
{
public:
std::string const attribute{"I'm a creature"s};
std::vector<std::string> attributes{attribute};
virtual void print()
{
for (auto& i : attributes)
std::cout << i << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { attributes.push_back(attribute); }
std::string const attribute{"I can swim"s};
};
class Flier : public virtual Creature
{
public:
Flier() { attributes.push_back(attribute); }
std::string const attribute{"I can fly"s};
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { attributes.push_back(attribute); }
std::string const attribute{"I'm a duck"s};
};
int main()
{
Duck d;
d.print();
}
Likewise, if it is not just printing we're after, but rather the function calls, then we could let the base class keep track of the functions:
#include <iostream>
#include <functional>
#include <vector>
class Creature
{
public:
std::vector<std::function<void()>> print_functions{[this] {Creature::print_this(); }};
virtual void print_this()
{
std::cout << "I'm a creature" << std::endl;
}
void print()
{
for (auto& f : print_functions)
f();
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { print_functions.push_back([this] {Swimmer::print_this(); }); }
void print_this()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
Flier() { print_functions.push_back([this] {Flier::print_this(); }); }
void print_this()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { print_functions.push_back([this] {Duck::print_this(); }); }
void print_this()
{
std::cout << "I'm a duck" << std::endl;
}
};
int main()
{
Duck d;
d.print();
}
An easy way is to create a bunch of helper classes that mimick the inheritance structure of your main hierarchy and do all the printing in their constructors.
struct CreaturePrinter {
CreaturePrinter() {
std::cout << "I'm a creature\n";
}
};
struct FlierPrinter: virtual CreaturePrinter ...
struct SwimmerPrinter: virtual CreaturePrinter ...
struct DuckPrinter: FlierPrinter, SwimmerPrinter ...
Then each print method in the main hierarchy just creates the corresponding helper class. No manual chaining.
For maintainability you can make each printer class nested in its corresponding main class.
Naturally in most real world cases you want to pass a reference to the main object as an argument to the constructor of its helper.
Your explicit calls to the print methods form the crux of the issue.
One way round this would be to drop the print calls, and replace them with say
void queue(std::set<std::string>& data)
and you accumulate the print messages into the set. Then it doesn't matter those functions in the hierarchy get called more than once.
You then implement the printing of the set in a single method in Creature.
If you want to preserve the order of printing, then you'd need to replace the set with another container that respects the order of insertion and rejects duplicates.
If you want that middle class method, do not call the base class method. The easiest and simplest way is to extract extra methods, and then reimplementing Print is easy.
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Creature::Print();
Flier::detailPrint();
Swimmer::detailPrint();
detailPrint();
}
void detailPrint()
{
std::cout << "I'm a duck" << std::endl;
}
};
Without details what is your actual problem is, it hard to come up with a better solution.
Use:
template<typename Base, typename Derived>
bool is_dominant_descendant(Derived * x) {
return std::abs(
std::distance(
static_cast<char*>(static_cast<void*>(x)),
static_cast<char*>(static_cast<void*>(dynamic_cast<Base*>(x)))
)
) <= sizeof(Derived);
};
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Walker : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can walk" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer, public Walker
{
public:
void print()
{
Walker::print();
Swimmer::print();
Flier::print();
std::cout << "I'm a duck" << std::endl;
}
};
And with Visual Studio 2015 the output is:
I'm a creature
I can walk
I can swim
I can fly
I'm a duck
But is_dominant_descendant does not have a portable definition. I wish it were a standard concept.
You are asking for something like inheritance on a function level that automatically calls the inherited function and just adds more code. Also you want it to be done in a virtual way just like class inheritance. Pseudo syntax:
class Swimmer : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
// Inherit from both prints. As they were created using "virtual function inheritance",
// this will "mix" them just like in virtual class inheritance
void print() : Flier::print(), Swimmer::print()
{
std::cout << "I'm a duck" << std::endl;
}
};
So the answer to your question
Is there some built-in way to do this?
is no. Something like this does not exist in C++. Also, I'm not aware of any other language that has something like this. But it is an interesting idea...
I'm trying to solve an inheritance problem, where a derived class Snake inherits from LivingThing -> Animal -> Reptile, however, when I don't add virtual void crawl() to class LivingThing, the compiler says error: no member named 'crawl' in 'LivingThing'. Now I don't want to have to implement a virtual void in LivingThing which is specific for Snakes.
#include <iostream>
class LivingThing
{
public:
void breathe()
{
std::cout << "I'm breathing as a living thing." << std::endl;
}
virtual void crawl() {} //dont' want this
};
class Animal : virtual public LivingThing
{
public:
void breathe()
{
std::cout << "I'm breathing as an animal." << std::endl;
}
};
class Reptile : virtual public LivingThing
{
public:
void crawl()
{
std::cout << "I'm crawling as a reptile." << std::endl;
}
void breathe()
{
std::cout << "I'm breathing as a reptile." << std::endl;
}
};
class Snake : public Animal, public Reptile
{
public:
void breathe()
{
std::cout << "I'm breathing as a snake." << std::endl;
}
void crawl()
{
std::cout << "I'm crawling as a snake." << std::endl;
}
};
int main()
{
LivingThing *snake = new Snake();
snake->breathe();
snake->crawl();
system("pause");
return 0;
}
snake->crawl(); tries to access crawl through a LivingThing*, without a v-table reference, LivingThing* cannot call Snake::crawl.
In your current example you could just change the LivingThing pointer to be a Snake pointer.
In a more complex situation:
If you know that the pointer you're calling crawl on points to an object that is infact a Snake then you can static_cast the pointer.
if(Snake* snake = static_cast<Snake*>(livingThing))
snake->crawl();
If you have no guarantee that the living thing is actually a Snake and you have rtti available then you can use dynamic_cast.
if(Snake* snake = dynamic_cast<Snake*>(livingThing))
snake->crawl();
When you upcast object to it's base type, you can only use methods which are declared in this base class. So if you don't want to declare crawl method in your base type, you've to downcast your object before using this method:
LivingThing *creature = new Snake();
creature->breathe();
if(Snake* snake = dynamic_cast<Snake*>(creature)) snake->crawl();
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.
I have the following two classes. Since Child inherits from Father, I think that Child::init() overrides Father::init(). Why, when I run the program, I get "I'm the Father" and not "I'm the Child"? How to execute Child::init()?
You can test it here: https://ideone.com/6jFCRm
#include <iostream>
using namespace std;
class Father {
public:
void start () {
this->init();
};
void init () {
cout << "I'm the father" << endl;
};
};
class Child: public Father {
void init () {
cout << "I'm the child" << endl;
};
};
int main (int argc, char** argv) {
Child child;
child.start();
}
Currently Child::init is hiding Father::init, not overriding it. Your init member function needs to be virtual in order to get dynamic dispatch:
virtual void init () {
cout << "I'm the father" << endl;
};
Optionally, you could mark Child::init as override to be explicit that you want to override a virtual function (requires C++11):
void init () override {
cout << "I'm the child" << endl;
};
You should define the function with function specifier virtual
For example
#include <iostream>
using namespace std;
class Father {
public:
virtual ~Father() {}
void start () {
this->init();
};
virtual void init () const {
cout << "I'm the father" << endl;
};
};
class Child: public Father {
void init () const override {
cout << "I'm the child" << endl;
};
};
int main()
{
Child child;
child.start();
return 0;
}
Otherwise function start searches name init in the scope of its own class. And because function init is not virtual that is it is not overriden in the derived class the base class function init is called.
If you want the child to override the init method, you must make the init method in the base class virtual.
class Father {
public:
void start () {
this->init();
};
virtual void init () {
cout << "I'm the father" << endl;
};
};
A class that re-declares and re-implements a virtual method of one of its bases, is said to override that method. In order for late binding to occur for a method, you need to declare that method virtual.