I am pretty new to C++ and I have a doubt on templates and polymorphism. So, I was making basic funcs with templates but then I thought that I wanna work with classes and try to do some inheriting. So can someone properly guide me?
I have tried a little only and I just got errors. I really am new so I don't know a lot... :P
Here's the code I have typed till now:
template <class temp>
class car{
public:
temp colour;
temp *ptcs = &colour;
temp setChar(temp a){
*ptcs = a;
}
virtual void sayChar()=0;
};
class lambo : public car<string>{
public:
void sayChar(){
cout << "My characteristic : " << *ptcs << endl;
}
};
class chiron : public car<string>{
public:
void sayChar(){
cout << "My characteristic : " << *ptcs << endl;
}
};
int main(){
}
I expect to inherit from car class and add more to it whilst being able to access and run code from both the derived classes in main()
Why the Pointer ptcs? There is no use for it. If you want to access private members of a base in a derived class, write a getter:
#include <string>
#include <iostream>
template <class T>
class car {
T colour;
public:
void setChar(T a) { colour = a; }
T getChar() const { return colour; }
};
class lambo : public car<std::string> {
public:
void sayChar() const {
std::cout << "My characteristic : " << getChar() << '\n';
}
};
class chiron : public car<std::string> {
public:
void sayChar() const {
std::cout << "My characteristic : " << getChar() << '\n';
}
};
int main()
{
lambo foo;
foo.setChar("red");
foo.sayChar();
chiron bar;
bar.setChar("blue");
bar.sayChar();
}
BTW, the search term you might be looking for is "Curiously recurring template pattern".
Related
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...
class man {
public:
void do_something();
}
int main(){
man Joe, Peter, Steve;
Joe.do_something();
Peter.do_something();
Steve.do_something();
return 0;
}
There is only one unique man called Joe. Same with Peter and Steve. And there is something unique about what they do. I may spawn hundreds of instances of man and I need to redefine do_something() function for each of them.
Two attempts I do not like:
1) Joe as a singleton class, that inherits from man.
2) passing a function pointer to do_something().
I want to redefine do_something() function for each instance of man. Is it possible?
The simplest thing to do is pass the action as a parameter to the constructor.
You could use a std::function or a lambda.
Or create another "action" class.
class Action
{
public:
virtual ~Action();
virtual void something() = 0;
};
If you inherit from this for the specifics of what you want, then each man can use the action in the do_something method.
A simple way is to use std::function to customize the behavior:
#include <iostream>
#include <functional>
class man {
public:
std::function<void()> something;
void do_something() { something(); }
}
int main(){
man Joe, Peter, Steve;
Joe.something = [] () { std::cout << "Joe something."; };
Joe.do_something();
Peter.something = [] () { std::cout << "Peter something."; };
Peter.do_something();
Steve.something = [] () { std::cout << "Steve something."; };
Steve.do_something();
return 0;
}
If you want more functionality I suggest having an abstract class that's added to the man class that requires overriding do_something(). Then inheriting from that class for each different action.
Yes. Look at the strategy design pattern:
https://en.wikipedia.org/wiki/Strategy_pattern
#include <memory>
#include <string>
#include <iostream>
class man {
public:
man (std::string const& name) : name_(name) {}
virtual void do_something() {
std::cout << name_ << " does it" << std::endl;
};
protected:
std::string name_;
};
class Joe : public man{
public:
Joe() : man("Joe") {}
};
class Fred : public man {
public:
Fred() : man("Fred") {}
virtual void do_something() override final {
man::do_something();
std::cout << " ... but Fred can do way more" << std::endl;
}
};
class ConcreteMan {
public:
ConcreteMan(std::string const& name) : man_(nullptr) {
if (name == "Joe")
man_.reset(new Joe());
else if (name == "Fred")
man_.reset(new Fred());
else
std::cerr << "No such man " << name << std::endl;
}
void do_something() {
if (man_ != nullptr)
man_->do_something();
else
std::cerr << "No real man" << std::endl;
}
private:
std::unique_ptr<man> man_;
};
int main() {
ConcreteMan joe("Joe"), fred("Fred"), donald("Donald");
joe.do_something();
fred.do_something();
donald.do_something();
return 0;
}
Solution 1: Tag dispatching
You can just add a type and write the behaviour.
struct Joe{ void do(){std::cout << "drink";} };
struct Peter{ void do(){std::cout << "smoke";} };
struct Steve{ void do(){std::cout << "sleep";} };
class man {
public:
template<typename T>
void do_something(){ T.do();}
}
since you have to call do_something() every time, you can consider saving the struct inside the man class, so you can rid of template:
struct man_detail{}
struct Joe : public man_detail{ void do(){std::cout << "drink";} };
struct Peter : public man_detail{ void do(){std::cout << "smoke";} };
struct Steve : public man_detail{ void do(){std::cout << "sleep";} };
class man{
public:
man(man_detail md) : maninfo(md){}
void do_something() { maninfo.do(); }
private:
man_detail maninfo;
};
in any time your man_detail can evolve to an interface and add more methods.
Solution 2: Template specialization
your man class become a template, so man and man are to completely different types you can just provides a partial specialization.
struct Joe{};
struct Peter{};
struct Steve{};
template <typename T>
class man
{
void do_something() {}
}
template <Joe> void man::do_something(){std::cout << "drink";}
template <Peter> void man::do_something(){std::cout << "smoke";}
template <> void man::do_something(){std::cout << "sleep";}
If I have a class that's inheriting from another, is it possible to replace the inherited class in the child? I've got a demo of what I'm trying to do below, but I'm not sure the syntax.
#include <iostream>
class singleNum
{
public:
int m_a;
singleNum(int a)
{
std::cout << "SETUP" << std::endl;
m_a = a;
}
~singleNum()
{
std::cout << "CLOSEDOWN" << std::endl;
}
};
class inheritor : public singleNum
{
public:
inheritor(int a) : singleNum(a) {};
reset(int b)
{
singleNum::this = *singleNum(b);
}
};
int main()
{
inheritor z(5);
std::cout << z.m_a << std::endl;
z.reset(5);
return 0;
}
No
You cannot exchange or reset the base class. If it had a reset method of it's own, you could call this, but you cannot call the constructor again.
If you want to do this, you should favor composition over inheritance. You can then create a completely new instance of the inner composition class and replace your existing instance.
Your current demo isn't hard to implement, but you'll need to modify the parent class:
#include <iostream>
class singleNum
{
public:
int m_a;
singleNum(int a)
{
std::cout << "SETUP" << std::endl;
reset(a);
}
~singleNum()
{
std::cout << "CLOSEDOWN" << std::endl;
}
virtual void reset(int b)
{
m_a = b;
}
};
class inheritor : public singleNum
{
public:
inheritor(int a) : singleNum(a) {}
void reset(int b) override
{
singleNum::reset(b);
}
};
int main()
{
inheritor z(5);
std::cout << z.m_a << std::endl;
z.reset(5);
return 0;
}
But this is the closest you will get to "replacing the base class". If your case is different than the demo presented and you need to call the base class constructor on an already constructed derived object then no, this is not doable.
I'm making an inventory system, and am trying to use derivatives to create different items, so that I can have default elements in the parent and specialized ones in the children.
So what I've written below, at the moment it prints "I'm a parent" but I am trying to get it to print "I'm a kid", and in the lack of a child definition of stuffToSay print "I'm a parent" Thanks!
using namespace std;
class myParent {
public:
virtual void saySomething() {
cout << stuffToSay;
}
string stuffToSay = "I'm a parent";
private:
};
class myDerivitive : public myParent{
public:
myDerivitive() {};
string stuffToSay = "I'm a kid";
private:
};
int main() {
myParent* people[] = {
new myDerivitive()
};
cout << people[0]->stuffToSay;
system("pause");
}
Thats not how it works. The saySomething in parent doesn't know anything about the string in the derived class and member variables aren't virtual.
You can do it e.g. like this
#include <iostream>
#include <string>
struct myParent {
void saySomething() {
cout << getSomething();
}
virtual std::string getSomething(){ return "I'm a parent"; }
virtual ~myParent(){} // virtual destructor is needed
};
struct myDerived : myParent {
virtual std::string getSomething(){ return "I'm the derived"; }
};
int main() {
myParent* p = new myDerived();
p->saySomething();
delete p; // dont forget to delete !!
}
Something like this is normally done using the constructor of your class, the child class has all the variables of its parent class so to do what you are looking for it can be done like this:
using namespace std;
class myParent {
public:
myParent() {
stuffToSay = "I'm a parent"
}
virtual void saySomething() {
cout << stuffToSay;
}
string stuffToSay;
private:
};
class myDerivitive : public myParent{
public:
myDerivitive() {
stuffToSay = "I'm a kid";
};
private:
};
int main() {
myParent* people = new myDerivitive();
cout << people->stuffToSay();
delete people; // Simplified to a single pointer and remember to delete it
people = NULL;
system("pause");
}
Please take a look at this link for more information on classes:
http://www.cplusplus.com/doc/tutorial/classes/
This link will help with the understanding of inheritance, since your derivative class would have the "stuffToSay" variable since its parent had it:
http://www.cplusplus.com/doc/tutorial/inheritance/
There is no such thing as a virtual or overridden variable in C++; that sort of polymorphism only applies to methods. So you could do this:
struct parent {
virtual void saySomething() {
cout << "I'm a parent!\n";
}
};
struct child: parent {
void saySomething() override {
cout << "I'm a child!\n";
}
};
Or you could solve it with something more like your current structure by adding a layer of indirection:
struct parent {
void saySomething() {
cout << thingToSay() << '\n';
}
private:
virtual string thingToSay() { return "I'm a parent!"; }
};
class child: parent {
virtual string thingToSay() { return "I'm a child!"; }
};
Is it possible to do such things in C++14. I have a base class as follows:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
class ConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //1
}
};
class SuperConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //2
}
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
As you can see at //1 and //2, the function's body is completely similar. But I can't quite move it into a base class because of depending on the static type of this. In spite of that fact, I wouldn't like to write absolutely the same code every time I need to add one more subclass of AbstractElement. So, I need some kind of mechanism which provides us with the facility to inject code into a function.
As long as marcos are not very desirable solution, I'd like to ask about some tricks that can be done in C++14 for solving such a problem.
Yes, it is possible using CRTP:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
template <class T>
class CRTPAbstractElement : public AbstractElement
{
B _b;
public:
virtual void foo()
{
T* t = dynamic_cast<T *>(this);
_b.bar(t);
}
};
class ConcreteElement : public CRTPAbstractElement<ConcreteElement>
{
};
class SuperConcreteElement : public CRTPAbstractElement<SuperConcreteElement>
{
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
By adding an intermediate CRTP class we are able to cast a pointer to the base class to a pointer to the derived class. Thus solving the issue of code duplication.