C++: how to define a class member with a reference - c++

Following my question, I coded a simple tool to compute a root using the bisection method, which is working fine. Here is the code:
roots.h
#ifndef ROOTS_H
#define ROOTS_H
class FunctRoots {
public:
// default constructor
FunctRoots();
// destructor
virtual ~FunctRoots();
// return the error
virtual double evaluate(double x);
};
class Roots{
private:
double tol=1e-5;
int max_iter=100;
double a, b;
double fa=0.0;
double fb=0.0;
public:
// default constructor
Roots();
// destructor
virtual ~Roots();
// set tolerance
void set_tolerance(double tolerance);
// set the search space
void set_search_space(double a, double b);
// bracketing
void bracketing(FunctRoots& problem, double start, double step);
// bisection method
double bisection(FunctRoots& problem);
};
#endif
roots.cpp
#include "roots.h"
#include "iostream"
#include "cmath"
// define the template for the function
FunctRoots::FunctRoots () {}
FunctRoots::~FunctRoots () {}
double FunctRoots::evaluate(double x){
return 0.0;
};
// Roots class
Roots::Roots() {}
Roots::~Roots() {}
// set search space
void Roots::set_search_space(double a, double b){
this->a = a;
this->b = b;
}
// set tolerance
void Roots::set_tolerance(double tolerance){
this->tol = tolerance;
}
// bracketing
void Roots::bracketing(FunctRoots& problem, double start, double step){
// set initial boundary
this->a = start;
this->fa = problem.evaluate(this->a);
// main loop
this->b = start;
for (int iter = 0; iter < max_iter; iter++) {
// update upper boundary
this->b += step;
this->fb = problem.evaluate(this->b);
// check if a root exists
if (this->fa*this->fb < 0) break;
// update lower bound
this->a = this->b;
this->fa = this->fb;
}
// check boundaries
if (this->a > this->b){
double temp;
temp = this->a;
this->a = this->b;
this->b = temp;
temp = this->fa;
this->fa = this->fb;
this->fb = temp;
}
}
// bisection method
double Roots::bisection(FunctRoots& problem){
// variables declaration
double fx, x;
// compute errors
if (fabs(this->fa) < 1e-12){
this->fa = problem.evaluate(this->a);
}
// main loop
x = 0;
for (int iter = 0; iter < max_iter; iter++) {
// compute solution
x = (a+b)/2.0;
fx = problem.evaluate(x);
// print on screen
std::cout << "iter=" << iter << "\n";
std::cout << "a=" << a << "\n";
std::cout << "b=" << b << "\n";
std::cout << "x=" << x << "\n";
std::cout << "fx=" << fx << "\n\n";
// stop criterion
if (fabs(fx) < this->tol) break;
// update boundaries
if (this->fa*fx < 0){
this->b = x;
}else{
this->a = x;
this->fa = fx;
}
}
// function return
return x;
}
main.cpp
#include "roots.h"
#include "cmath"
class Problem: public FunctRoots{
private:
double value;
public:
Problem(double value){
this->value = value;
}
double evaluate(double x) {
return pow(cos(x),2)+this->value-x;
}
};
int main(){
Problem problem(6);
Roots roots;
//roots.set_search_space(5, 10);
roots.set_tolerance(1e-7);
roots.bracketing(problem, 0,0.1);
roots.bisection(problem);
return 0;
}
Now, the question is this: how can I make my main looks like this?
int main(){
Problem problem(6);
Roots roots;
roots.set_problem(problem) // <----NEW
//roots.set_search_space(5, 10);
roots.set_tolerance(1e-7);
roots.bracketing(0,0.1); // <---- problem is not here anymore
roots.bisection(); // <---- problem is not here anymore
return 0;
}
Basically, I would like to define my problem once and for all just after initializing the solver so that I don't need to give it as input to the functions anymore, however considering that the function evaluate is defined in FunctRoots but then overridden in Problem.

I would like to define my problem once and for all just after initializing the solver …
You can add a reference to a FunctRoots object as a member of your Roots class:
class Roots {
private:
FunctRoots& problem;
double tol = 1e-5;
//...
However, rather than initializing this "just after initializing the solver", you would need to intialize it at the time of creating that solver (i.e., pass it as a parameter to the constructor and initialize the member variable in an initializer list). So, your Roots constructor would then look like this:
Roots::Roots(FunctRoots& fr) : problem{ fr } {}
You can then (as you desire) remove the reference to the Problem object in your bracketing and bisection methods, and your main would look like:
int main() {
Problem problem(6);
Roots roots(problem); // Initializes reference member at construction
roots.set_tolerance(1e-7);
roots.bracketing(0, 0.1); // <---- problem is not here anymore
roots.bisection(); // <---- problem is not here anymore
return 0;
}
Note that such reference members must be initialized at object construction time; they cannot then be reassigned to refer to different objects. Also note that polymorphism works with references, just as it does with pointers.

How to define a class member with a reference
It's as simple as that, just declare a member reference and create a constructor to initialize it:
class Member{};
class MyClass{
Member& member;
public:
MyClass(Member& m) : member(m) {}
};
int main(){
Member m;
MyClass cl(m);
}
Note that the lifetime of Member must be at least the same as MyClass otherwise you will end up with a dangling referece.

In this case, I think your root class should either
have member variable "problem", and initialize it when you call roots.set_problem(problem).
like
class Roots {
private:
Problem *myProblem;
public:
void set_problem(Problem &problem){
myProblem = new Problem(problem.value)
}
}
or have other variable members that could store value you give with roots.set_problem(problem).

Related

C++ How do I return an object containing a pointer without triggering the destructor?

code looks like this
#include<iostream>
class A
{
public:
int* a;
char name;
A(char _n = 'N')
{
a = 0;
name = _n;
}
A(int _a, int _b, char _n = 'N')
{
name = _n;
a = new int[2]{ _a, _b };
}
~A()
{
std::cout << "deleting object..." << name << "\n";
delete[] a;
}
//
void operator=(A b)
{
std::cout << "cleanup begin\n";
delete[] a;
a = new int[] {b.a[0], b.a[1]};
}
//
A Copy()
{
if (a == 0) return *new A();
A* _r = new A(a[0], a[1], name + 1);
return *_r;
}
};
//
int main()
{
A d{0, 1, 'T'};
{
A Z(0, 1);
Z = Z.Copy();
}
std::cout << "check\n";
return 0;
}
I want Z = Z.Copy() to work but instead it triggers a breakpoint in delete_scalar.
From what i understand, the overloaded = should free the memory that is allocated to member a, after which it should allocate new memory and copy the integers by value, then destroying b.
Even so, object Z from the nameless scope has its destructor called twice, leading to the breakpoint trigger.
All that I want is to be able to do something like this:
x = (x - y) * z + y;
where I can overload = for x to assign to it the result of overloaded object operations (x and y are custom vector3 instances, z is a custom Matrix4 instance, Matrix4 contains a float*, if that's relevant).
So, what is the problem and how do I solve it?

parameterized constructor with dynamic array of object

In the below program i have used two classes , and i am trying to relate the with aggregation, i have declare class A as private in class B, and with the help of constructor i am initizing base address of class A object to private member of class B object that is (A object). i am trying to pass the class A values to class B usng parametrized constructor, but i am getting garbage values like,
#include <iostream>
using namespace std;
void create (B * &obj2, int siz)
{
std::cout << obj2[0].get_nn (); //this will run fine
for (int i = 0; i < siz; i++)
obj2[i] = B (10, "pranjal"); //this will also run fine
std::cout << obj2[0].get_nn ();
}
// same line printing again, this will not give output
// ***************************************
void display ()
{
std::cout << object.get_data () << object.get_stringdata ();
}
// giving garbage values
// why is it happening
// *********************************program
// ************************************** enter code here
// Online C++ compiler to run C++ program online
class A {
int rool;
string name;
public:
A () { };
A (int a, string name);
int get_data () {
return rool;
}
string get_stringdata () {
return this->name;
}
};
A::A (int a, string name)
{
this->rool = a;
this->name = name;
}
void getdetails (A * obj)
{
for (int i = 0; i < 3; i++)
obj[i] = A (20, "pranjal");
}
class B {
int bbb;
string name;
A object;
public:
B () {};
B (A s) {
object = s;
}
string get_nn () {
return object.get_stringdata ();
}
B (int a, string b);
void display () {
std::cout << object.get_data () << object.get_stringdata ();
}
};
void dis (B * obj2)
{
for (int i = 0; i < 2; i++) {
obj2[i].display ();
}
}
void create (B * &obj2, int siz)
{
std::cout << obj2[0].get_nn ();
for (int i = 0; i < siz; i++)
obj2[i] = B (10, "pranjal");
std::cout << obj2[0].get_nn () << "sd";
}
B::B (int a, string b)
{
bbb = a;
name = b;
}
int main ()
{
A *obj = new A[3];
getdetails (obj);
B *obj2 = new B[3];
for (int i = 0; i < 3; i++) {
obj2[i] = B (obj[i]);
}
create (obj2, 3);
dis (obj2);
obj2->display ();
return 0;
}
In create, you fully replace the previous B objects with brand new ones using the 2 parameters constructor... which just leaves the A object member default initialized.
What could be done to fix?
Pass the parameters of B to A ctor:
B::B (int a, string b): object(a, b)
{
bbb = a;
name = b;
}
That way you initialize the A object member with the same parameters as its parent
Reset the A object member to its previous value:
void create (B * &obj2, int siz)
{
std::cout << obj2[0].get_nn (); //this will run fine
for (int i = 0; i < siz; i++) {
A old = obj2[i].object;
obj2[i] = B (10, "pranjal"); //this will also run fine
obj2[i].object = old;
}
std::cout << obj2[0].get_nn ();
}
But as it requires accesses to private members, create should be declared friend in B class:
class B {
...
friend void create (B * &obj2, int siz);
};
void create(B *&obj2,int siz)
{
std::cout<<obj2[0].get_nn(); //this will run fine
for(int i=0;i<siz;i++)
obj2[i]=B(10,"pranjal");
std::cout<<obj2[0].get_nn(); // same line printing again, this will not give output
}
Of course it won't: B(int, std::string) does not call a constructor of A explicitly, so A's default constructor is called. This implicitly calls name's default constructor, too, which will create an empty string.
For a similar reason you get garbage values: Your default constructor does not assign a value to rool, thus leaves it uninitialised; it will remain at the value that was there in memory before, which ever it was, which is what you consider 'garbage'.
This occurs because with obj2[i] = B(10,"pranjal") a new object is created and then copied into the target object (with optimisations, can be created directly in place, but obviously you cannot rely on).
Fix your constructor of A to assign a value to rool and the problem should go away. You might chose a non-zero value to have a more clearly visible effect:
A() : rool(1977) { }
Alternatively you can provide provide a default value to rool (requires C++11):
int rool = 1977;
That can be convenient especially if you have a larger number of constructors.
In general: You should not leave primitive types of any of your objects uninitialised to avoid similar problems.

Missing Constructor for Initialization

Hi I am trying to debug a program and one of the errors I am receiving is 'Missing Initialization for Constructor'. Do I need to declare the vector upfront and how do I initialize it?
#include <iostream>
#include <vector>
using namespace std;
class Point {
private:
double x;
double y;
public:
double get_x() { return x; }
double get_y() { return y; }
bool set_x(double arg) {
x = arg;
return true;
}
bool set_y(double arg) {
y = arg;
return true;
}
Point() : x(0), y(0) {}
Point(double argx, double argy) : x(argx), y(argy) {
}
};
class Vector {
private:
Point A;
Point B;
public:
Point get_A() { return A; }
Point get_B() { return B; }
Vector(const Point &arg1, const Point &arg2) : A(arg1), B(arg2)
{
//this->A = arg1;
//this->B = arg2;
//A = arg1;
//B = arg2;
}
void set_A(const Point &arg) {
A = arg;
}
void set_B(const Point &arg) {
B = arg;
}
static Vector add_vector(const Vector &vector1, const Vector &vector2) {
if (&vector1.B != &vector2.A) {
//Error 1 Vector V1 No Matching constructor for initialization for 'vector'
Vector rval;
return rval;
}
Point one = vector1.A;
Point two = vector2.B;
Vector newvector(one, two);
//newvector.A = one;
//newvector.B = two;
return newvector;
}
Vector add_vector(const Vector &arg) {
// Type of this? Vector *; These three lines are equivalent:
//Point one = this->A;
//Point one = (*this).A;
Point one = A;
Point two = arg.B;
Vector newvector(one, two);
//newvector.A = one;
//newvector.B = two;
return newvector;
}
};
int main() {
//Error 2 Vector v No Matching constructor for initialization for 'vector'
Vector v;
cout << "(" << v.get_A().get_x() << ", " << v.get_A().get_y() << "),\n" <<
"(" << v.get_B().get_x() << ", " << v.get_B().get_y() << ")\n";
//Error 3 Vector V1 No Matching constructor for initialization for 'vector'
Vector v1(1,2), v2(2,3);
Vector res = Vector::add_vector(v1, v2);
cout << "(" << res.get_A().get_x() << ", " << res.get_A().get_y() << "),\n" <<
"(" << res.get_B().get_x() << ", " << res.get_B().get_y() << ")\n";
}
Your issue here is your class is not default constructable.
Vector rval;
Requires a default constructor. Since you provided a user defined constructor the compiler will no longer make a default constructor for you.
To create a default constructor for Vector you can use
Vector() = default;
If you have C++11 or higher or you can use
Vector() {}
For pre C++11.
I am not sure what you are trying to do with
Vector v1(1,2)
Vector needs two Points and each Point needs 2 values.

I want to create a loop within a class

I have a class that contains a variable 'beta'. I want to run the code with 1000 different values of 'beta' that range between 0 and 1. My first thought was to run a loop but I am unable to do this within a class. I also have tried using pointers but this did not seem to work. I apologise if my question is rather amateur but I am a Math grad, not computer science. Can someone please help!
The code for my class is listed below.
class FalknerSkan : public MFunction
{
public:
//constuctor to initialise kappa
FalknerSkan() {beta = 0.0;}
MVector operator()(const double& x, const MVector& y)
{//y[0]=f, y[1]=f', y[2]=f'', y[3]=Z1, y[4]=Z2, y[5]=Z3
MVector temp(6);
temp[0] = y[1];
temp[1] = y[2];
temp[2] = -y[0]*y[2] - beta*(1-y[1]*y[1]);
temp[3] = y[4];
temp[4] = y[5];
temp[5] = -y[2]*y[3] + 2.0*beta*y[1]*y[4] - y[0]*y[5];
return temp;
}
void SetKappa(double k) {beta = k;} //change kappa
private:
double beta; // class member variable, accessible within
//all FalknerSkan member functions
};
Thank you
This is a loop inside a class.
#include <iostream>
class Foo
{
public:
Foo() : beta(0.0)
{}
void print(){
for (int i(0); i < 1000; ++i)
std::cout << ++beta << std::endl;
}
private:
double beta;
};
int main()
{
Foo obj;
obj.print();
return 0;
}

C++ function pointer (class member) to non-static member function

class Foo {
public:
Foo() { do_something = &Foo::func_x; }
int (Foo::*do_something)(int); // function pointer to class member function
void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }
private:
int func_x(int m) { return m *= 5; }
int func_y(int n) { return n *= 6; }
};
int
main()
{
Foo f;
f.setFunc(false);
return (f.*do_something)(5); // <- Not ok. Compile error.
}
How can I get this to work?
class A{
public:
typedef int (A::*method)();
method p;
A(){
p = &A::foo;
(this->*p)(); // <- trick 1, inner call
}
int foo(){
printf("foo\n");
return 0;
}
};
void main()
{
A a;
(a.*a.p)(); // <- trick 2, outer call
}
The line you want is
return (f.*f.do_something)(5);
(That compiles -- I've tried it)
"*f.do_something" refers to the pointer itself --- "f" tells us where to get the do_something value from. But we still need to give an object that will be the this pointer when we call the function. That's why we need the "f." prefix.
class A {
int var;
int var2;
public:
void setVar(int v);
int getVar();
void setVar2(int v);
int getVar2();
typedef int (A::*_fVar)();
_fVar fvar;
void setFvar(_fVar afvar) { fvar = afvar; }
void insideCall() { (this->*fvar)(); }
};
void A::setVar(int v)
{
var = v;
}
int A::getVar()
{
std::cout << "A::getVar() is called. var = " << var << std::endl;
return var;
}
void A::setVar2(int v2)
{
var2 = v2;
}
int A::getVar2()
{
std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
return var2;
}
int main()
{
A a;
a.setVar(3);
a.setVar2(5);
// a.fvar = &A::getVar;
a.setFvar(&A::getVar);
(a.*a.fvar)();
a.setFvar(&A::getVar2);
(a.*a.fvar)();
a.setFvar(&A::getVar);
a.insideCall();
a.setFvar(&A::getVar2);
a.insideCall();
return 0;
}
I extended Nick Dandoulakis's answer. Thank you.
I added a function which set the member function pointer from outside of the class. I added another function which can be called from outside to show inner call of member function pointer.
Try (f.*do_something)(5);
#include<iostream>
using namespace std;
class A {
public:
void hello()
{
cout << "hello" << endl;
};
int x = 0;
};
void main(void)
{
//pointer
A * a = new A;
void(A::*pfun)() = &A::hello;
int A::*v1 = &A::x;
(a->*pfun)();
a->*v1 = 100;
cout << a->*v1 << endl << endl;
//-----------------------------
A b;
void(A::*fun)() = &A::hello;
int A::*v2 = &A::x;
(b.*fun)();
b.*v2 = 200;
cout << b.*v2 << endl;
}
I think calling a non static member of the class could also be done using a static member function.