I have two classes: MovableObject and GravitySource that inherited from MovableObject (because GravitySources can move too). At MovableObject I have function integrate that calculates movement params using list of GravitySources.
So, I can't put list of GravitySources into this function. And I don't want to create duplicates of MovableObject functions (including integrate) in GravitySource. So, how to solve this problem? It is C++.
Your MovableObject::integrate function declaration can take a MovableObject* pointer as a parameter, something like:
return_type MovableObject::integrate(Movable* );
In this way, you can pass GravitySources to the Movable::integrate, and the behaviour will be polymorphic, i.e. you have access to virtual functions via the pointer to base MovableObject*. Therefore make sure you have some common virtual functions that can be called via the pointer to base, and delegate the work to them.
If you want to pass an array of GravitySources, then it's a bit more tricky, since you cannot safely use a MovableObject* pointer to move through a GravitySources array. What you can do though is to forward-declare the class GravitySources, then you can declare
return_type MovableObject::integrate(GravitySources* );
You can use incomplete types via pointers, so the above declaration is OK. Just make sure the implementation of the function comes after the full definition of GravitySources. You can now pass arrays of GravitySources to your function!
Some toy example below:
#include <iostream>
class GravitySources; // need this forward declaration
class MovableObject
{
public:
void integrate(GravitySources* gs, std::size_t N); // process N GravitySources
virtual void f(); // our common virtual interface
virtual ~MovableObject() = default;
};
class GravitySources: public MovableObject
{
int _label; // label the instance
public:
GravitySources(int label): _label(label) {}
void f() override;
};
void MovableObject::integrate(GravitySources* gs, std::size_t N)
{
// process the GravitySources
for (std::size_t i = 0; i < N; ++i)
{
gs[i].f();
}
}
void MovableObject::f()
{
std::cout << "MovableObject::f()" << std::endl;
}
void GravitySources::f()
{
std::cout << "GravitySources::f() " << _label << std::endl;
}
int main()
{
MovableObject mo;
GravitySources gs[3] {1, 2, 3}; // 3 GravitySources
mo.integrate(gs, 3); // process them
}
Related
I have an abstract base class called BaseStrategy. It contains one pure virtual function calculateEfficiency(). There are two classes ConvolutionStrategy and MaxPoolStrategy which derive from this base class and implement their own specific version of calculateEfficiency().
Here is some code:
class BaseStrategy {
public:
explicit BaseStrategy();
virtual ~BaseStrategy() = default;
private:
virtual double calculateEfficiency(mlir::Operation* op) = 0;
};
class ConvolutionStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for convolution
return 1;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for MaxPool
return 1;
}
};
Now I have another class called StrategyAssigner. It has method calculateAllLayerEfficiencies() whose purpose is to iterate over all layers in a network. Depending on the type of layer there is a switch statement and should call the correct calculateEfficiency() depending on the layer type.
class StrategyAssigner final {
public:
explicit StrategyAssigner(){};
public:
void calculateAllLayerEfficiencies() {
// Logic to iterate over all layers in
// a network
switch (layerType) {
case Convolution:
// Call calculateEfficiency() for Convolution
break;
case MaxPool:
// Call calculateEfficiency() for MaxPool
break;
}
};
}
int main ()
{
StrategyAssigner assigner;
assigner.calculateAllLayerEfficiencies();
}
My question is, should I store references of objects Convolution and MaxPool in the class StrategyAssigner so that I can call the respective calculateEfficiency().
Or could you suggest a better way to call calculateEfficiency(). I don't really know how to create the objects (stupid as that sounds).
I can't make calculateEfficiency() static as I need them to be virtual so that each derived class can implemented its own formula.
If you included complete code I could give a more detailed answer, but you need to store BaseStrategy pointers that are initialized with derived class instances. Here's an example made from some of your code:
std::vector<std::unique_ptr<BaseStrategy>> strategies;
strategies.emplace_back(new ConvolutionStrategy);
strategies.emplace_back(new MaxPoolStrategy);
for (int i = 0; i < strategies.size(); ++i) {
std::unique_ptr<BaseStrategy>& pStrat = strategies[i];
pStrat->calculateEfficiency(...);
}
Note that this won't compile because I don't have enough details from the code you posted to make it so, but this shows how to exploit polymorphism in the way that you need.
Also, I used smart pointers for memory management; use these at your discretion.
You can indeed use runtime polymorphism here:
Declare ~BaseStrategy virtual (you are already doing it ;-)
If you are never going to instantiate a BaseStrategy, declare one of its methods as virtual pure, e.g. calculateEfficiency (you are already doing it as well!). I would make that method const, since it doesn't look it's going to modify the instance. And it will need to be public, because it will need to be accessed from StrategyAnalyser.
Declare calculateEfficiency as virtual and override in each of the subclasses. It could also be final if you don't want subclasses to override it.
I'd keep a std::vector of smart pointers to BaseStrategy at StrategyAssigner. You can use unique_ptrs if you think this class is not going to be sharing those pointers.
The key point now is that you create heap instances of the subclasses and assign them to a pointer of the base class.
class StrategyAssigner final {
public:
void addStrategy(std::unique_ptr<BaseStrategy> s) {
strategies_.push_back(std::move(s));
}
private:
std::vector<std::unique_ptr<BaseStrategy>> strategies_{};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
}
Then, when you call calculateEfficiency using any of those pointers to BaseStrategy, the runtime polymorphism will kick in and it will be the method for the subclass the one that will be actually called.
class ConvolutionStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "ConvolutionStrategy::calculateEfficiency()\n";
return 10;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "MaxPoolStrategy::calculateEfficiency()\n";
return 20;
}
};
class StrategyAssigner final {
public:
void calculateAllLayerEfficiencies() {
auto sum = std::accumulate(std::cbegin(strategies_), std::cend(strategies_), 0,
[](auto total, const auto& strategy_up) {
return total + strategy_up->calculateEfficiency(); });
std::cout << "Sum of all efficiencies: " << sum << "\n";
};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
assigner.addStrategy(std::make_unique<MaxPoolStrategy>());
assigner.calculateAllLayerEfficiencies();
}
// Outputs:
//
// ConvolutionStrategy::calculateEfficiency()
// MaxPoolStrategy::calculateEfficiency()
// Sum of all efficiencies: 30
[Demo]
Right now I have a base class, class Base{}, with two classes deriving from it, BFS{} and DFS{}. BFS has queue, and DFS has stack, so they both have a member called "nodes", but the type is their respective std::queue and std::stack. My search function takes in a pointer to base class as its parameter so that it can accept both derived classes, and runs the search by pushing and popping from the member classes inside the derived classes (as per the usual DFS BFS algorithms). The issue is, since I passed in my base class as the parameter, whenever I try to call push or pop on the member stack/queue called "nodes" from the derived classes, it always says that the push/pop cannot be done because there is no member inside the base class called "nodes". How am I supposed to make this work?
Also, this setup is a requirement of the assignment I am doing and I just can't figure out how this is supposed to work, any help is appreciated.
Thanks!
class Base {
public:
virtual void push(uint64_t roomID, float intensity, int distance) = 0;
virtual Node pop(void) = 0;
virtual int size(void) = 0;
};
class Breadth : public Base {
public:
std::queue<std::pair<uint64_t, int>> U;
void push(uint64_t roomID, float intensity, int distance) { std::pair<uint64_t, int> p(roomID, distance); U.push(p); }
Node pop() { Node rr; rr.ID = U.front().first; rr.distance = U.front().second; U.pop(); return rr; }
int size() { return U.size(); }
};
class Depth : public Base {
public:
std::stack<std::pair<uint64_t, int>> U;
void push(uint64_t roomID, float intensity, int distance) { std::pair<uint64_t, int> p(roomID, distance); U.push(p); }
UnexploredRoom pop() { U.pop(); }
int size() { U.size(); }
};
void robotSearch::searchLoop(Base* search, Discovered* D, uint64_t roomID)
{
Node room;
room.ID = roomID;
room.distance = 0;
search->U.push(room); //problem here, compiler wont let me push U
...
}
To implement custom behaviour through a pointer to a base class, you need to use virtual functions. Another approach would be to use generic code with templates.
Example:
class Base {
public:
virtual ~Base() {}
virtual void push(int i) = 0;
virtual int pop() = 0;
};
class DFS : public Base{
public:
virtual void push(int i) override { /*...*/ }
virtual int pop() override { /*...*/ return {}; }
};
class BFS : public Base {
public:
virtual void push(int i) override { /*...*/ }
virtual int pop() override { /*...*/ return {}; }
};
Right now, you have some virtual methods push and pop, but for some reason, you don't use them and instead try to access a member of the derived classes instead. You seem to have copied code from the answer by Ayjay but not applied it correctly.
That member U should really not be exposed like this, that is, it should be private, and you should use your class methods to manipulate it.
Therefore, you wouldn't write
search->U.push(room);
even if it was legal here (which it isn't, as the base class does not have anything named like that).
Instead, you go with
search->push(room);
Note that I omitted the other arguments that this takes, of course you also have to provide values for your intensity and distance arguments.
Doing so will call the appropriate method, that is either Breadth::push or Depth::push, which then will access the corresponding member of the respective class.
By the way, for reasons of control, you should use the override keyword as Ayjay did, and also, you should give a member a more descriptive name that U.
I've been wondering if it's possible for the client / user to decide what function to run from the class.
For example, Say I have the following function:
std::vector<double> greeks_mesh_pricer(const Greeks& Greek, (function to Run), int mesh_size) {
std::vector<double> result;
for(int i = 0; i < mesh_size; i += mesh_size) {
result.push_back(Greek.(function to run));
}
}
Function to run, is a member function of the Greek class. Greeks here is an interface containing pure virtual functions, so the user is actually passing
in a Derived class of Greeks. So if the client specifies the function Delta(), it returns a vector of Delta() results, etc.
You can do it with pointers to member functions:
#include <iostream>
struct Base {
virtual ~Base() {}
virtual void foo() const = 0;
virtual void bar() const = 0;
};
struct Derived1 : Base {
void foo() const { std::cout << "Derived1::foo\n"; }
void bar() const { std::cout << "Derived1::bar\n"; }
};
struct Derived2 : Base {
void foo() const { std::cout << "Derived2::foo\n"; }
void bar() const { std::cout << "Derived2::bar\n"; }
};
void invoke(const Base &b, void (Base::*func)() const) {
(b.*func)();
}
int main() {
Derived1 d1;
Derived2 d2;
invoke(d1, &Base::foo);
invoke(d2, &Base::foo);
invoke(d1, &Base::bar);
invoke(d2, &Base::bar);
}
Output
Derived1::foo
Derived2::foo
Derived1::bar
Derived2::bar
Windows has implemented that sort of automation with IDispatch, you can implement a similar one if not using Windows. The idea is to specify a function by ID (or translated from a name) and to pass the arguments as VARIANTs.
You might be asking about function pointers in C++. Just like a pointer can be use to reference a variable or object, similarly pointers can be used to reference a function as well and you can also pass a function to a function using these pointers or create an array of pointers where each pointer is actually a function pointer (reference to a function).
Read here : https://www.cprogramming.com/tutorial/function-pointers.html
You can use std::function to represent and store a function. You can also use std::bind and std::placeholder to facilitate the whole thing. Example:
struct A {
int f(int);
int g(int);
};
A instance;
std::function<int(int)> client_fn;
using namespace std::placeholders;
if (...) {
client_fn = std::bind(&A::f, &instance, _1);
} else {
client_fn = std::bind(&A::g, &instance, _1);
}
I have 10 Coin types: BTC, ETH, Shift etc. For this I have a superclass "Coin" and subclasses for each of those coins. Then I have a pointer to a "Coin" type, so that I can call each of the subclasses no matter what subtype they are.
Problem is, I only know how to do this in Java and not in C++. I have a hard time searching for the correct terms, because I don't really know what to search for other than "generics". What I want is something like this:
// Superclass
class Coin {
public:
virtual void handleCoin();
};
// Subclass
class BTC: public Coin {
void handleCoin();
}
BTC::BTC() = default;
BTC::~BTC() = default;
BTC::handleCoin() {
std::cout << "handling BTC" << std::endl;
}
// Subclass
class ETH: public Coin {
void handleCoin();
}
ETH::ETH() = default;
ETH::~ETH() = default;
ETH::handleCoin() {
std::cout << "handling ETH" << std::endl;
}
// Execute
int main() {
Coin* coin;
coin = BTC();
coin.handleCoin();
coin = ETH();
coin.handleCoin();
return 0;
}
I want this to print:
handling BTC
handling ETH
I know I need to work with templates, but I cannot find a specific example of this specific case.
Also, my constructors don't take arguments, so I guess my template declaration would be something like
template<>
Yet all the examples I see work with
template<typename T>
and then use type T as function arguments like calling
max<float, float>
max<double, double>
But that's not what I'm looking for. Is there a way to translate this example above to working C++ code?
From the code posted I don't see a need for templates, virtual methods work without templates. To fix your code in main you need to use pointers/references and also have a virtual destructor.
class Coin {
public:
virtual void handleCoin();
virtual ~Coin()=default;
};
class BTC: public Coin {
public:
BTC::BTC() = default;
//Destructor of a derived class is automatically virtual if the base class's one is.
void handleCoin();
}
// Subclass
class ETH: public Coin {
void handleCoin();
ETH::ETH() = default;
//Still virtual even if you specify otherwise
ETH::~ETH() = default;
}
int main() {
Coin* coin;
coin = new BTC();//Returns BTC* <--pointer
coin->handleCoin();
delete coin;//Calls Coin::~Coin() -> thus the need for virtual so BTC::~BTC is called instead.
coin = new ETH();
coin->handleCoin();
delete coin;//Same, calls ETH::~ETH()
return 0;
}
Manual memory management is error-prone, from C++11 there's a better approach which should be strongly preferred:
int main() {
std::unique_ptr<Coin> coin;//Hides the pointer, but still has pointer-like semantics
coin = std::make_unique<BTC>();
coin->handleCoin();
//Automatically frees old memory
coin = std::make_unique<BTC>();
coin->handleCoin();
//Calls unique ptr's dtor because coin is local variable, which again frees the memory correctly.
return 0;
}
I'm trying to take advantage of the polymorphism in c++, but I'm from a c world, and I think what I've done could be done more cleverly in a OOP way.
I have 2 classes that has exactly the same public attributes, and I want to "hide" that there exists 2 different implementations. Such that I can have a single class where I can use the member functions as If i were accessing the specific class.
An very simple implementation of what I'm trying to accomplish is below:
#include <iostream>
class subber{
private:
int id;
public:
int doStuff(int a,int b) {return a-b;};
};
class adder{
private:
int id;
public:
int doStuff(int a, int b) {return a+b;};
};
class wrapper{
private:
int type_m;
adder cls1;
subber cls2;
public:
wrapper(int type) {type_m=type;};//constructor
int doStuff(int a, int b) {if(type_m==0) return cls1.doStuff(a,b); else return cls2.doStuff(a,b);};
};
int main(){
wrapper class1(0);
std::cout <<class1.doStuff(1,3) <<std::endl;
wrapper class2(1);
std::cout <<class2.doStuff(1,3) <<std::endl;
return 0;
}
I have 2 classes called "subber" and "adder" which both have a member function called doStuff, which will either subtract of add 2 numbers.
This I wrap up in a class "wrapper", which has both "adder" and "subber" as private variables, and a doStuff public member function. And given which value I instantiate my "wrapper" class with, my "wrapper" class will simply relay the "doStuff" to the correct class.
This code does of cause work, but I would like to avoid instatiating both "subber" and "adder" in my wrapper class, since I will only need of them in each of my "wrapper" classes.
Thanks
There are many ways to do it. Through a Factory for example.
But to keep it simple - make a base abstract class that defines the interface, and derive your classes from it to implement the functionality. Then you only need to make the distinction once, when you create the class, after that you don't care, you just call the interface functions.
your code would look something like that.
class DoStuffer
{
public:
virtual int doStuff(int, int)=0;
virtual ~DoStuffer(){}; // Because Tony insists:-) See the comments
}
class subber: public DoStuffer{
public:
virtual int doStuff(int a,int b) {return a-b;};
};
class adder: public DoStuffer{
public:
virtual int doStuff(int a, int b) {return a+b;};
};
int main(){
DoStuffer *class1 = new adder();
DoStuffer *class2 = new subber();
std::cout <<class1->doStuff(1,3) <<std::endl;
std::cout <<class2->doStuff(1,3) <<std::endl;
delete class1; // don't forget these:-)
delete class2;
return 0;
}
This is one of the more idiomatic ways to use the C++ class system to accomplish what you want. Both adder and subber publicly inherit from wrapper, which is now an abstract base class. The doStuff method is now a (pure) virtual function. And instead of being a simple instance of wrapper, the "encapsulated" object is now a reference to a wrapper.
#include <iostream>
class wrapper {
public:
virtual int doStuff(int a, int b) = 0;
};
class subber : public wrapper {
public:
virtual int doStuff(int a,int b) {return a - b;}
};
class adder : public wrapper {
public:
virtual int doStuff(int a, int b) {return a + b;}
};
int main(){
// actual objects
adder impl1;
subber impl2;
// in real code, the wrapper references would probably be function arguments
wrapper& class1 = impl1;
std::cout << class1.doStuff(1,3) << std::endl;
wrapper& class2 = impl2;
std::cout << class2.doStuff(1,3) << std::endl;
return 0;
}
(Not using any factory pattern in this example, since it's not obvious that it's needed or what the question is about.)
Exactly what was last said.
Make a base class, and have a virtual function |doStuff| in it.
Then you can derive any number of classes out from it, all have to implement the above virtual function, in whatever way they want to.
Then you can just do the following
BaseClass *object1 = new DerivedClass1();
BaseClass *object2 = new DerivedClass2();
..
You can even do
object1 = object2;
And then they point to the same object (i.e. an object of type |DerivedClass2|)
But remember, when you do objectn->doStuff(), the function that will be executed will be what the pointer points to at run-time, and not at compile time.
i.e. if I do object1->doStuff() DerivedClass2's doStuff will be called because we already did `object1 = object2;
You may want to Google and read about
Polymorphism/ Run-time Polymorphism
Virtual Functions in C++
You can read Factory Method, which is something that is known as a Design Pattern, but later in life.
Thanks
The classic run-time polymorphic approach is:
struct Operation
{
virtual ~Operation() { } // guideline: if there are any virtual functions,
// provide virtual destructor
virtual int doStuff(int, int) const;
};
struct Subber : Operation
{
int doStuff(int a, int b) const { return a - b; }
};
struct Adder : Operation
{
int doStuff(int a, int b) const { return a + b; }
};
enum Operations { Add, Subtract };
struct Operation* op_factory(Operations op)
{
if (op == Add) return new Adder;
if (op == Subtract) return new Subber;
throw std::runtime_error("unsupported op");
}
int main()
{
Operation* p1 = op_factory(Add);
std::cout << p1->doStuff(1,3) <<std::endl;
Operation* p2 = op_factory(Subtract);
std::cout << p2->doStuff(1,3) <<std::endl;
delete p1;
delete p2;
}
From the Standard 5.3.5/5 "In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined.", which is why you must use the virtual keyword on the base class destructor.
It's noteworthy that in your example the type of operation to perform was communicated to the wrapper class using a function argument of 0 or 1... this is what suggests you want run-time polymorphism. For example, if the 0 or 1 value was based on a command line argument, file content, keyboard input etc., then the factory method above can pass a corresponding Add or Subtract value and receive an appropriately-behaving object derived from Operation. This concept of creating an instance of a run-time polymorphic type based on run-time values is known as a factory.
If you really only need compile-time polymorphism, you can do some interesting things with templates such as:
template <class Operation>
void output(int a, int b)
{
std::cout << Operation::doStuff(a, b) << std::endl;
std::cout << Operation::doStuff(a * 10, b * 10) << std::endl;
std::cout << Operation::doStuff(a * 100, b * 100) << std::endl;
}
int main()
{
output<adder>(1, 3);
output<subber>(1, 3);
}
FWIW, your approach is probably slightly faster than the virtual function approach (as it can potentially do more inlining), but not as clean, extensible, maintainable or scalable.
I think what you're looking for is virtual functions. If you declare a function virtual in your base class, you can do things like make a vector containing multiple objects derived from your base class, but when you call on a particular object it will execute it's own method.