Skip to main content
Code Review

Return to Question

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

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:

  1. That is an ugly place to have a new operator, could it be avoided somehow?
  2. 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:

  1. That is an ugly place to have a new operator, could it be avoided somehow?
  2. 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:

  1. That is an ugly place to have a new operator, could it be avoided somehow?
  2. 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++

edited tags; edited title
Link
200_success
  • 145.5k
  • 22
  • 190
  • 478

Fluent interface and polymorphism for building a scene with shapes

deleted 3 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

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:

  1. That is an ugly place to have a new operator, could it be avoided somehow?
  2. 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:

  1. That is an ugly place to have a new operator, could it be avoided somehow?
  2. 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:

  1. That is an ugly place to have a new operator, could it be avoided somehow?
  2. 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++

added 199 characters in body
Source Link
DarioP
  • 917
  • 1
  • 9
  • 22
Loading
edited tags
Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Loading
added 1 characters in body
Source Link
DarioP
  • 917
  • 1
  • 9
  • 22
Loading
Tweeted twitter.com/#!/StackCodeReview/status/437900081187291136
deleted 5 characters in body
Source Link
DarioP
  • 917
  • 1
  • 9
  • 22
Loading
Source Link
DarioP
  • 917
  • 1
  • 9
  • 22
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /