Need to access Oject returned as answer to function as pointer

I've been working on this two days and I have'nt figured it out so I decided to put all the code here and ask for help. I have a class NonlinearSolver that has another class "SolutionNLE" as a data member. NonLinearsolver also has a child class Nonlinearsolver_bisection that should solve a math problem (Function1D class and MyFunc1 ) and return the answer as an instance of the class Solution NLE. The problem I have is accessing the object that is returned from the solve function in the Nonlinearsolver class (starting line 105). I want to be able to access the answer from the main function something like line 151 and 152 but that doesnt work because nlesolution is private but making a function to call a function to return a member of another class seems like bad programming. Line 150 works but i would have to output the answer through the function and cannot access it in the main class. Does anyone have any clue as to how to do something like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include <iostream>
#include <math.h>
using namespace std;
namespace csc350Lib_calc_base {
 class Function1D {
  public:
    Function1D(void){};                    
    virtual ~Function1D(void){};             
    virtual float func(float x) = 0;         
    virtual float dfunc(float x);          
    virtual bool  isExactDerivativeDefined(void) = 0;  
};	
}

//-------------------------------------------------------
using namespace csc350Lib_calc_base;
namespace csc350Lib_calculus_snle {
 typedef enum SolutionStatus {
  SEARCH_SUCCESSFUL = 0,
  SEARCH_FAILED_TOO_MANY_ITERATIONS = 1,
  SEARCH_FAILED_OUT_OF_RANGE = 2,
  SEARCH_FAILED_NUMERICAL_ERROR = 3,
  SEARCH_FAILED_OTHER_REASON = 4
} SolutionStatus;

class SolutionNLE{
public:
  SolutionNLE(){}; //Default constructor
  SolutionStatus getStatus(void); 
  float getSolution(void);          
  float getValueAtSolution(void);  
  int   getNumberOfIterations(void); 
  void  setSolution(float);
  void  setFuncValue(float);
  void  setIterations(int);
  ~SolutionNLE();
private:
  float solution;
  float funcValue;
  int   numOfIterations;
  SolutionStatus status;
};
void SolutionNLE::setSolution(float answer)
{
	solution = answer;
}
float SolutionNLE::getSolution(void)
{
	return solution;
}
float SolutionNLE::getValueAtSolution(void)
{
	return funcValue;
}
void SolutionNLE::setFuncValue(float answer)
{
	funcValue = answer;
}
int SolutionNLE::getNumberOfIterations(void)
{
	return numOfIterations;
}
void SolutionNLE::setIterations(int iterations)
{
	numOfIterations = iterations;
}
SolutionNLE::~SolutionNLE(){}
//--------------------------------------------------

class NonlinearSolver {
public:
  NonlinearSolver(void);
  static const SolutionNLE * solve(Function1D* f, float a, float b, float tol);
 ~NonlinearSolver();
private:
  SolutionNLE * nleSolution;
};
NonlinearSolver::NonlinearSolver()
: nleSolution(){}
NonlinearSolver::~NonlinearSolver(){}
}
//-----------------------------------------------------------------
using namespace csc350Lib_calculus_snle;
//---------------------------------------------------------------
class MyFunc1 : public Function1D {
public: 
	float func(float);
	bool isExactDerivativeDefined(void);
	
};


float MyFunc1::func(float x)
{
	return  cos(x+5);
	
}

bool MyFunc1::isExactDerivativeDefined(void)
{
	return false;
}
//-----------------------------------------------------------------
class NonlinearSolver_bisection : public NonlinearSolver {};
const SolutionNLE* NonlinearSolver::solve(Function1D *f, float a, float b, float tol)
{
	SolutionNLE *nleSolution = new SolutionNLE;
	float  fa = f->func(a);
	float  fb = f->func(b);
	float  c  = (a+b)/2;
	int iterations = 1;
	float tolerance = 2 * tol;
	while ((b-a > tolerance ) && (c != a) && (c != b)){
		float fc = f->func(c);
		if ((fc * fa) > 0 ) {
			a = c;
			fa = fc;
		}
		else if (fc != 0){
			b = c;
			fb = fc;
		}
		else {
			nleSolution->setIterations(iterations);
			nleSolution->setFuncValue(f->func(c));
			nleSolution->setSolution(c);
			return nleSolution;
		}
		c = (a + b)/2;
		iterations++;
		

	}
	nleSolution->setIterations(iterations);
	nleSolution->setFuncValue(f->func(c));
	nleSolution->setSolution(c);
	cout << nleSolution->getSolution()  << " f(c) soulution "<< endl;
	cout << nleSolution->getValueAtSolution() << " value at solution" << endl;
	cout << nleSolution->getNumberOfIterations() << " number of iterations " << endl;
	return nleSolution;
}
int main (int argc, char * const argv[]) {
	Function1D  *f1;
    f1 = new MyFunc1();
	
	
	
	NonlinearSolver *nls;
	nls = new NonlinearSolver_bisection();
	nls->solve(f1, 1., 4., 0.01);
        nls->nleSolution = nls->solve(f1, 1., 4., 0.01);
	nls->nleSolution->getSolution();
		
    float   x = 3.f;
    float   y1 = f1->func(x),
	    dy1 = f1->dfunc(x);

	cout << y1  << endl;
	
	cout << dy1 << endl;
	
	
	
	return 0;
}









I'm not sure I understand you
const SolutionNLE* NonlinearSolver::solve(Function1D *f, float a, float b, float tol) You already return the solution. However you don't have any methods in SolutionNLE that will allow you to communicate (it is not const correct)
But you will be violating Demeter if you try to send a message to the returned object.
An alternative is to ask to the solver to print the solution
1
2
3
void NonlinearSolver::print_solution(){
  nleSolution->print_solution();
}


Why setter and getter methods are evil http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=1
Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.
SolutionNLE could be a simple struct or use the constructor to giving it its state, and add real methods.

1
2
3
4
5
6
7
8
9
10
const SolutionNLE* NonlinearSolver::solve(Function1D *f, float a, float b, float tol)
{
	SolutionNLE *nleSolution = new SolutionNLE; //this is a local variable (not the member)
//...
class NonlinearSolver_bisection : public NonlinearSolver {}; //Does not work. You need to declare the methods
//...
class NonlinearSolver {
public:
  NonlinearSolver(void);
  static const SolutionNLE * solve(Function1D* f, float a, float b, float tol); //static? 
You need virtual to use the polymorphism. But you can't make a method static and virtual. If you don't plan to use polymorphism, then don't use pointers.
What about
1
2
3
4
5
6
7
8
9
10
class NonlinearSolver{
public:
  virtual const SolutionNLE * solve();
}

class NonlinearSolver_bisection : public NonlinearSolver {
public:
  NonlinearSolver_bisection(Function1D* f, float a, float b, float tol);
  virtual const SolutionNLE * solve();
}; 
The only reason line 73 is static const is because that is the prototype my teacher gave me to work with. I don't know if he just made a typo or if there is some way that I am supposed to make this work.
I do have functions in solutionNLE to communicate the answers (lines 43 - 66) I just dont know how to get access to them since the solutionNLE i want to access is a data member of the class Nonlinearsolver_bisection.
Topic archived. No new replies allowed.