I would like to improve the interfaces of some polymorphic classes going from positional to named parameters and I came up with the fluent interface.
The following is the most clean, compact and compilable (-std=c++11 required) example that I have been able to come up with:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
struct Figure {
string _name;
Figure * name(const string & str) { _name=str; return this; }
virtual double area() const=0;
};
struct Circle: Figure {
double _radius;
Circle * radius(double r) { _radius=r; return this;}
double area() const override {return M_PI*_radius*_radius;}
};
struct Square: Figure {
double _side;
Square * side(double s) { _side=s; return this;}
double area() const override {return _side*_side;}
};
struct Scene {
vector<Figure*> v;
~Scene() { for (auto & f : v) delete f; }
Scene & add(Figure * f) {v.push_back(f); return *this;}
double total_area() const {
double total=0;
for (auto f : v) total += f->area();
return total;
}
};
int main() {
Scene scene;
scene.add((new Circle)->radius(1.)->name("c1"))
.add((new Square)-> side(1.)->name("s1"));
cout << "Total area: " << scene.total_area() << endl;
return 0;
}
I have a couple of issues with this:
- That is an ugly place to have a
new
operator, could it be avoided somehow? - After having called the method
name("name")
the type is lost so there is still an ordering to respect:add((new Square)->name("s1")->side(1.))
will not compile. You should imagine to have many levels of inheritance and lots of parameters to be setted!
How would you address these issues and improve the code? C++1y is allowed and preferred to Boost?
For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++ Variadic templates and pointers to member functions to achieve a named-parameters interface in C++
I would like to improve the interfaces of some polymorphic classes going from positional to named parameters and I came up with the fluent interface.
The following is the most clean, compact and compilable (-std=c++11 required) example that I have been able to come up with:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
struct Figure {
string _name;
Figure * name(const string & str) { _name=str; return this; }
virtual double area() const=0;
};
struct Circle: Figure {
double _radius;
Circle * radius(double r) { _radius=r; return this;}
double area() const override {return M_PI*_radius*_radius;}
};
struct Square: Figure {
double _side;
Square * side(double s) { _side=s; return this;}
double area() const override {return _side*_side;}
};
struct Scene {
vector<Figure*> v;
~Scene() { for (auto & f : v) delete f; }
Scene & add(Figure * f) {v.push_back(f); return *this;}
double total_area() const {
double total=0;
for (auto f : v) total += f->area();
return total;
}
};
int main() {
Scene scene;
scene.add((new Circle)->radius(1.)->name("c1"))
.add((new Square)-> side(1.)->name("s1"));
cout << "Total area: " << scene.total_area() << endl;
return 0;
}
I have a couple of issues with this:
- That is an ugly place to have a
new
operator, could it be avoided somehow? - After having called the method
name("name")
the type is lost so there is still an ordering to respect:add((new Square)->name("s1")->side(1.))
will not compile. You should imagine to have many levels of inheritance and lots of parameters to be setted!
How would you address these issues and improve the code? C++1y is allowed and preferred to Boost?
For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++
I would like to improve the interfaces of some polymorphic classes going from positional to named parameters and I came up with the fluent interface.
The following is the most clean, compact and compilable (-std=c++11 required) example that I have been able to come up with:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
struct Figure {
string _name;
Figure * name(const string & str) { _name=str; return this; }
virtual double area() const=0;
};
struct Circle: Figure {
double _radius;
Circle * radius(double r) { _radius=r; return this;}
double area() const override {return M_PI*_radius*_radius;}
};
struct Square: Figure {
double _side;
Square * side(double s) { _side=s; return this;}
double area() const override {return _side*_side;}
};
struct Scene {
vector<Figure*> v;
~Scene() { for (auto & f : v) delete f; }
Scene & add(Figure * f) {v.push_back(f); return *this;}
double total_area() const {
double total=0;
for (auto f : v) total += f->area();
return total;
}
};
int main() {
Scene scene;
scene.add((new Circle)->radius(1.)->name("c1"))
.add((new Square)-> side(1.)->name("s1"));
cout << "Total area: " << scene.total_area() << endl;
return 0;
}
I have a couple of issues with this:
- That is an ugly place to have a
new
operator, could it be avoided somehow? - After having called the method
name("name")
the type is lost so there is still an ordering to respect:add((new Square)->name("s1")->side(1.))
will not compile. You should imagine to have many levels of inheritance and lots of parameters to be setted!
How would you address these issues and improve the code? C++1y is allowed and preferred to Boost?
For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++
Fluent interface and polymorphism for building a scene with shapes
EDIT: For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++
I would like to improve the interfaces of some polymorphic classes going from positional to named parameters and I came up with the fluent interface.
The following is the most clean, compact and compilable (-std=c++11 required) example that I have been able to come up with:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
struct Figure {
string _name;
Figure * name(const string & str) { _name=str; return this; }
virtual double area() const=0;
};
struct Circle: Figure {
double _radius;
Circle * radius(double r) { _radius=r; return this;}
double area() const override {return M_PI*_radius*_radius;}
};
struct Square: Figure {
double _side;
Square * side(double s) { _side=s; return this;}
double area() const override {return _side*_side;}
};
struct Scene {
vector<Figure*> v;
~Scene() { for (auto & f : v) delete f; }
Scene & add(Figure * f) {v.push_back(f); return *this;}
double total_area() const {
double total=0;
for (auto f : v) total += f->area();
return total;
}
};
int main() {
Scene scene;
scene.add((new Circle)->radius(1.)->name("c1"))
.add((new Square)-> side(1.)->name("s1"));
cout << "Total area: " << scene.total_area() << endl;
return 0;
}
I have a couple of issues with this:
- That is an ugly place to have a
new
operator, could it be avoided somehow? - After having called the method
name("name")
the type is lost so there is still an ordering to respect:add((new Square)->name("s1")->side(1.))
will not compile. You should imagine to have many levels of inheritance and lots of parameters to be setted!
How would you address these issues and improve the code? C++1y is allowed and preferred to boost.Boost?
For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++
EDIT: For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++
I would like to improve the interfaces of some polymorphic classes going from positional to named parameters and I came up with the fluent interface.
The following is the most clean, compact and compilable (-std=c++11 required) example that I have been able to come up with:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
struct Figure {
string _name;
Figure * name(const string & str) { _name=str; return this; }
virtual double area() const=0;
};
struct Circle: Figure {
double _radius;
Circle * radius(double r) { _radius=r; return this;}
double area() const override {return M_PI*_radius*_radius;}
};
struct Square: Figure {
double _side;
Square * side(double s) { _side=s; return this;}
double area() const override {return _side*_side;}
};
struct Scene {
vector<Figure*> v;
~Scene() { for (auto & f : v) delete f; }
Scene & add(Figure * f) {v.push_back(f); return *this;}
double total_area() const {
double total=0;
for (auto f : v) total += f->area();
return total;
}
};
int main() {
Scene scene;
scene.add((new Circle)->radius(1.)->name("c1"))
.add((new Square)-> side(1.)->name("s1"));
cout << "Total area: " << scene.total_area() << endl;
return 0;
}
I have a couple of issues with this:
- That is an ugly place to have a
new
operator, could it be avoided somehow? - After having called the method
name("name")
the type is lost so there is still an ordering to respect:add((new Square)->name("s1")->side(1.))
will not compile. You should imagine to have many levels of inheritance and lots of parameters to be setted!
How would you address these issues and improve the code? C++1y is allowed and preferred to boost.
I would like to improve the interfaces of some polymorphic classes going from positional to named parameters and I came up with the fluent interface.
The following is the most clean, compact and compilable (-std=c++11 required) example that I have been able to come up with:
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
struct Figure {
string _name;
Figure * name(const string & str) { _name=str; return this; }
virtual double area() const=0;
};
struct Circle: Figure {
double _radius;
Circle * radius(double r) { _radius=r; return this;}
double area() const override {return M_PI*_radius*_radius;}
};
struct Square: Figure {
double _side;
Square * side(double s) { _side=s; return this;}
double area() const override {return _side*_side;}
};
struct Scene {
vector<Figure*> v;
~Scene() { for (auto & f : v) delete f; }
Scene & add(Figure * f) {v.push_back(f); return *this;}
double total_area() const {
double total=0;
for (auto f : v) total += f->area();
return total;
}
};
int main() {
Scene scene;
scene.add((new Circle)->radius(1.)->name("c1"))
.add((new Square)-> side(1.)->name("s1"));
cout << "Total area: " << scene.total_area() << endl;
return 0;
}
I have a couple of issues with this:
- That is an ugly place to have a
new
operator, could it be avoided somehow? - After having called the method
name("name")
the type is lost so there is still an ordering to respect:add((new Square)->name("s1")->side(1.))
will not compile. You should imagine to have many levels of inheritance and lots of parameters to be setted!
How would you address these issues and improve the code? C++1y is allowed and preferred to Boost?
For further improvements see the related question: Variadic templates and pointers to member functions to achieve a named-parameters interface in C++