Bjarne Stroustrup “Programming Principles and Practice Using C++”
Chapter 15 Exercise 3
[code language=”cpp”]
// Philipp Siedler
// Bjarne Stroustrup’s PP
// Chapter 15 Exercise 3
#define _USE_MATH_DEFINES
#include "Simple_window.h"
#include "Graph.h"
#include <cmath>
typedef double Fct(double);
double one(double x) { return 1; }
double slope(double x) { return x / 2; }
double square(double x) { return x * x; }
double sloping_cos(double x) { return cos(x) + slope(x); }
double sum_sin_cos(double x) { return sin(x) + cos(x); }
double sum_sin_cos_sq(double x) { return sin(x) * sin(x) + cos(x) * cos(x); }
template <class T> class myFct : Shape {
public:
myFct(Fct* f, double r1, double r2, Point orig, int count = 100, double xscale = 25, double yscale = 25, T precision = 1.0);
~myFct() {}
void set_f(Fct* p) { f = p; }
void set_r1(double r) { r1 = r; }
void set_r2(double r) { r2 = r; }
void set_orig(Point o) { orig = o; }
void set_count(int c) { count = c; }
void set_xscale(double x) { xscale = x; }
void set_yscale(double y) { yscale = y; }
void set_precision(T p) { precision = p; }
double get_r1() { return r1; }
double get_r2() { return r2; }
Point get_orig() { return orig; }
int get_count() { return count; }
double get_xscale() { return xscale; }
double get_yscale() { return yscale; }
T get_precision() { return precision; }
void calc();
void reset(Fct* f, double r1, double r2, Point orig, int count = 100, double xscale = 25, double yscale = 25, T precision = 1.0);
private:
Fct* f;
double r1;
double r2;
Point orig;
int count;
double xscale;
double yscale;
T precision;
};
template <class T> myFct<T>::myFct(Fct* f, double r1, double r2, Point orig, int count, double xscale, double yscale, T precision)
:f(f), r1(r1), r2(r2), orig(orig), count(count), xscale(xscale), yscale(yscale), precision(precision)
{
calc();
}
template <class T> void myFct<T>::calc()
{
if (r2 – r1 <= 0) error("bad graphing range");
if (count <= 0) error("non-positive graphing count");
double dist = (r2 – r1) / count;
double r = r1;
for (int i = 0; i < count; ++i) {
cout << f(r) << endl;
int x = orig.x + int(int(r * xscale) / precision) * precision;
int y = orig.y – int(int(f(r) * yscale) / precision) * precision;
add(Point(x, y));
r += dist;
}
}
template <class T> void myFct<T>::reset(Fct* f, double r1, double r2, Point orig, int count, double xscale, double yscale, T precision)
{
set_f(f);
set_r1(r1);
set_r2(r2);
set_orig(orig);
set_count(count);
set_xscale(xscale);
set_yscale(yscale);
set_precision(precision);
calc();
}
int main()
try
{
int min = 0;
int max = 5;
Point origin(0, 0);
int count = 5;
double xscale, yscale = 25;
myFct<double> MF(one, min, max, origin, count, xscale, yscale, 2.0);
cout << "—" << endl;
MF.reset(slope, min, max, origin, count, xscale, yscale, 3.0);
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << ‘\n’;
keep_window_open();
return 1;
}
catch (…) {
cerr << "Unknown exception!\n";
keep_window_open();
return 2;
}
[/code]
Output: 1 1 1 1 1 --- 0 0.5 1 1.5 2 Please enter a character to exit
Hey there! First of all super cool of you to share all your solutions 🙂
I had a question about this, was wondering if you knew the answer.
I’ve tried solving this by deriving my Function class (lets call it Fct2) from Function. It passes it’s constructor arguments to the constructor of the base Function class, which works fine and draws everything correctly, and also stores them in a way similar to yours
For the reset functions, i made a test one which only changes the function passed in. It stores the new function and calls the parent Function::Function, passing in the stored parameters. This does NOT work. If i try your solution, by copy/pasting the Function::Function into a void calc(); function,, for some reason it does work even though its the exact same stuff.
Would you know why? Thanks!
Hey, maybe worth posting your Function::Function 🙂