I am working on improving my C++ skills - specifically the use of templates. I am creating a filtering mathematical library that through the use of templates is compatible for different vector/matrix classes including Boost and Eigen. So far I am very happy with the library, but am encountering issues as I am expanding functionality.
Eigen and Boost are different in that for example the latter does not have multiply operators (see 1) so this presented a choice in my implementation. I decided to make sure that the matrix/vector methods and operators used within the template library use those that are defined for Eigen so that at least one library works really well with the mathematical library. In my library I would use * to multiply matrices which is unavailable for boost. For boost I created a wrapper class for both matrix and vector to allow the use of * through custom operators. Example of wrapper for matrix is below:
class matrixBoost{
private:
boost::numeric::ublas::matrix<double> value;
public:
matrixBoost(){
}
matrixBoost(boost::numeric::ublas::matrix<double> value):value(value){}
static matrixBoost Identity(int dimension,int dimension2){
return matrixBoost(boost::numeric::ublas::identity_matrix<double>(dimension,dimension2));
}
matrixBoost transpose(){
matrixBoost t(boost::numeric::ublas::trans(value));
return t;
}
boost::numeric::ublas::matrix<double> getSystemValue() const{
return value;
}
};
//example operator - one of many
matrixBoost operator*(const matrixBoost &lhs, const matrixBoost &rhs){
matrixBoost res(boost::numeric::ublas::prod(lhs.getSystemValue(),rhs.getSystemValue()));
return res;
}
I am now trying to add Eigen's block to boost's wrapper class that allows for the following behaviour in Eigen's library:
Eigen::MatrixXd m(2,2);m<<1,2,3,4;
Eigen::MatrixXd n = m.block(0, 0, 1, 2) + m.block(0,0,1,2);
m.block(0,0,1,2) = n;
with m now equalling
2 4
3 4
My first question is can someone please link or show examples of how the block function would be coded (without considering a wrapper class even). I have tried googling but either Google has gotten worse or I am not using the right key words - the results are swarmed with operator[] results. I am having difficulty understanding. I tried searching within the Eigen library source and imagine the code must be located here but the template language is a little difficult for me to parse easily.
I know that boost also has a similar concept as shown in here:
project(A, r1, r2) = C; // assign the submatrix of A specified by the two index ranges r1 and r2
C = project(A, r1, r2); // the submatrix of A specified by the two index ranges r1 and r2
I am not sure if adding a block function to my wrapper class is even possible. For now I have the following:
matrixBoost block(int index1,int index2, int length1, int length2){
boost::numeric::ublas::range r1(i1,l1);
boost::numeric::ublas::range r2(i2,l2);
return matrixBoost(boost::numeric::ublas::project(value,r1,r2));
}
This will work for when the method is on the right hand side of the the equal sign. However, I am having difficulty as to how to proceed to allowing for the method being called on the left hand side. Perhaps I should make use of boost's project method. Any help would be much appreciated!
Thank you.
So I found a solution for the problem of wrapping the boost class, but the solution is a little messy. The block function as deduced in the question above must return a reference. If it is on the right hand side of the equal sign then we need to return the submatrix wrapped within matrixBoost for the other */+ multiplications that might be in the expression. However, what if this is called on the left hand side of the equal sign?
My solution was to use a boolean flag (subMatrixCopy) where I would set it to true as well as backup the full matrix value in valBack through the use of std::swap and return with the submatrix. This modification would allow for proper expression evaluation on the right hand side. For the left hand side, once the = operator is called then the boolean flag makes sure that the right hand side is properly assigned to the specified block of the backed up matrix value in valBack.
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/qvm/mat_operations.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <lapacke.h>
class matrixBoost{
private:
boost::numeric::ublas::matrix<double> value;
boost::numeric::ublas::range r1;
boost::numeric::ublas::range r2;
boost::numeric::ublas::matrix<double>valBack;
bool subMatrixCopy = false;
void setSystemValue(boost::numeric::ublas::matrix<double> v){
value = v;
}
public:
matrixBoost(){}
matrixBoost(int rowCount, int colCount){
value = boost::numeric::ublas::zero_matrix<double>(rowCount,colCount);
}
matrixBoost(boost::numeric::ublas::matrix<double> value):value(value){}
static matrixBoost Identity(int dimension,int dimension2){
return matrixBoost(boost::numeric::ublas::identity_matrix<double>(dimension,dimension2));
}
matrixBoost transpose(){
matrixBoost t(boost::numeric::ublas::trans(value));
return t;
}
boost::numeric::ublas::matrix<double> getSystemValue() const{
return value;
}
matrixBoost & block(int i1, int i2, int l1, int l2){
if(subMatrixCopy){
std::swap(valBack,value);
}
subMatrixCopy = true;
r1 = boost::numeric::ublas::range(i1,i1+l1);
r2 = boost::numeric::ublas::range(i2,i2+l2);
valBack = boost::numeric::ublas::project(value,r1,r2);
std::swap(valBack,value);
return *this;
}
matrixBoost &operator=( const matrixBoost other){
if(subMatrixCopy){
subMatrixCopy = false;
boost::numeric::ublas::project(valBack,r1,r2) = other.getSystemValue();
std::swap(valBack,value);
}else{
value = other.getSystemValue();
}
return *this;//better be no chaining of equal signs
}
};
and here is an example of the code in action that I used to test. It works! However, I believe the solution prevents doing certain things such as chaining equal signs.
int main(){
boost::numeric::ublas::matrix<double> value(3,3);
value(0,0) = 1;
value(1,1) = 2;
value(2,2) = 3;
matrixBoost valueWrap(value);
boost::numeric::ublas::vector<double> v(3);
v(0) = 1;
v(1) = 1;
v(2) = 1;
cout<<vectorBoost::solve(valueWrap,vectorBoost(v))<<endl;
cout<<valueWrap<<endl;
matrixBoost newMatrix = valueWrap.block(1,1,2,2);
cout<<newMatrix<<endl;
cout<<valueWrap.block(1,1,2,2)<<endl;
valueWrap.block(1,1,2,2) =
valueWrap.block(1,1,2,2)*newMatrix + newMatrix;
cout<<valueWrap<<endl;
}
Related
So I am doing some tinkering with inheritance and abstract classes. In the instance I am programming I have created an array of pointers to Shape, my abstract base class. After filling the first 2 spots in the array with Square subclass pointers, I fill the third with the sum of the previous two. This gives me an "expression must have integral or unscoped enum type" error, which is giving me some trouble. Additionally, it gives me the error "'+' cannot add two pointers."
#include <iostream>
#include <cmath>
#include <string>
#include "Shape.h"
#include "Square.h"
using namespace std;
int main()
{
Shape** shapes = new Shape*[3];
shapes[0] = new Square(12);
shapes[1] = new Square(4);
shapes[2] = shapes[0] + shapes[1];
delete[] shapes;
return 0;
}
Interestingly enough, if I set the third index equal to the second index it works fine.
Here are my Square operators below.
Square& Square::operator=(const Square& c1)
{
if (this != &c1)
{
this->length_O = c1.GetLength();
this->width_O = c1.GetWidth();
}
return *this;
}
Square& Square::operator+=(const Square& c1)
{
if (this != &c1)
{
this->length_O = c1.GetLength();
this->width_O = c1.GetWidth();
}
return *this;
}
const Square Square::operator+(const Square& c1) const
{
return Square(*this) += c1;
}
Any ideas?
Unable to try compiling your code since the class definitions were not available.
At a glance, this line of code does not look correct.
shapes[2] = shapes[0] + shapes[1];
shapes[2] is a pointer to shape, but you have not created an instance of shape for that index off of the heap yet. So something like this may fix your issue, however once again I was not able to test this since the class definitions were not available in the original post
shapes[2] = new Square();
*shapes[2] = *shapes[0] + *shapes[1];
In regards to your implementation working when you simply set the third index equal to the second index; that probably works because it sounds like you are setting your third index to point to the same address that your second index is pointing to. If so, that is valid since they are just addresses
I have to implement a class Vector, which sets coordinates of a multi-dimensional vector and will work when called with this specific code (I can't change this part):
const int NumOfDimensions = 5;
Vector x (NumOfDimensions);
x.Set(0, 1.1).Set(1, 1.2).Set(2, 1.3).Set(3, 1.4).Set(4, 1.5);
x.print();
and the output has to be like this:
(1.1, 1.2, 1.3, 1.4, 1.5)
This is what I tried but couldn't get it to work:
class Vector {
float *coordinates;
int dimensions;
public:
Vector(int k)
{
coordinates = new float[k];
dimensions = k;
}
void Set(int k, float wsp)
{
//Vector x(k+1);
coordinates[k] = wsp;
//return x;
}
void print()
{
int i;
cout<<"(";
for(i=0; i<dimensions; i++)
cout<<coordinates[i]<<", ";
cout<<")"<<endl;
}
};
So I know function Set needs to be changed and probably return an object but I have tried lots of different ways and it just doesn't work. How should I modify it?
If you want to be able to chain methods of that sort you need to return a reference:
Vector& Set(int k, float wsp) {
// ...
return *this;
}
I'd argue that even though you see a lot of that in other languages like Python, Ruby and so on, that interface isn't very C++.
You'd be better off using std::vector to store your coordinates, the C-style arrays are nothing but trouble. This code actually has a severe memory leak since you don't de-allocate with delete[], there's no destructor defined. Using a Standard Library container offloads that responsibility.
Another thing you can do to make this more natively C++ is to define a formatter for it so you can simply dump this to cout directly instead of having a clunky method called print which does it for you:
std::ostream& operator<<(std::ostream& stream, const Vector& vec);
That will permit the use of that formatter on any stream, not just cout.
I am writing a code for Cellular Automata and I need an evolution function to calculate the state of the automata after a time step.
I choose to call this function evol, to test it I created an elementary function in C++. Unfortunately it does not compile since the compiler cannot understand that I need it to return an array. Here is the code :
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
const int N = 51; // Size of the grid; two columns/rows are added at the beginning and the end of the array (no evolution of the CA on the boundaries)
class Cell{
//defining whats a cell here
};
void showCA(Cell CA[N+2][N+2]){
//function to print the CA grid in the terminal
}
Cell[N+2][N+2] evol(Cell CA[N+2][N+2]){
return CA;
}
int main()
{
// Initialisation
cout << "Initialisation" << endl;
static Cell CA[N+2][N+2];
// some code here to initialize properly the Cell array.
showCA(CA);
CA = evol(CA);
showCA(CA);
return 0;
}
The compiler returns this error :
error: expected unqualified-id
Cell[N+2][N+2] evol(Cell CA[N+2][N+2]){
Any idea on how I should implement this ?
You cannot return arrays from functions:
ยง 8.3.5/8
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.
If you are wishing to return raw, C-style arrays from functions, then you have to use a reference or pointer. For example, here's how it is done using a reference (you can do the same using a pointer by replacing & with *):
Cell (&evol(Cell (&CA)[N+2][N+2]))[N+2][N+2];
However, this is very unintuitive and hard to read. If your compiler supports the latest standard (C++11) the return type can be cleaned up using a trailing return type:
auto evol(Cell (&CA)[N+2][N+2]) -> Cell(&)[N+2][N+2];
But again, this is probably still harder to read.
C++11 facilitates the handling of C-style arrays with the container std::array<>. Non-C++11 code should use std::vector<>:
using Cells = std::array<std::array<Cell, N+2>, N+2>;
Cells const& evol(Cells const& CA);
You can use
typedef std::vector<std::vector<Cell>> CellArray;
CellArray Cells(N+2); // resize main dimension
for (size_t i=0; i<N+2; i++)
Cells[i].resize(N+2); // resize all cells of main dimension
to hold your cell array, but you also need to add a copy constructor and operator= in Cell class
class Cell {
public:
Cell() { ... default ctor code here ... }
Cell(const Cell &c) { *this = c; }
Cell &operator=(const Cell&c)
{
if (this != &c)
{
... copy data from c members to this members here ...
}
return *this;
}
};
Your evol function then can return a CellArray:
CellArray evol(CellArray &c)
{
CellArray r;
... do some calculations with c and r ...
return r;
}
once you have declared a variable using the array syntax like you have:
Cell CA[N+2][N+2];
you cannot assign CA to be something else. You can only assign values to its contents. Hence,
CA = evol(CA);
is wrong.
You can do the following:
Cell (*CA2)[N+2] = evol(CA);
As the number of elements seems to be fixed, I suggest you use the std::array container:
const int N = 51;
typedef std::array<std::array<Cell,N+2>, N+2> datatype;
You can then use this type as a return type:
datatype Evol( const datatype& d );
You can access elements just as if it was a "C" array:
datatype d;
Cell c;
d[10][20] = c;
I would strongly suggest encapsulate your array into a class. You cannot return an array, but you can return an object that contains an array.
I have a C++ class containing a bunch of data members of the same type and I want to iterate over them:
// C.h
class C {
// other members
double foo;
double bar;
...
double barf; // 57th double declared since foo, nothing else in between
// other members
};
Pointer arithmetic seems to work, e.g. here using the constructor to initialize those 58 member doubles:
// C.cpp
C::C() {
for (int i = 0; i < 58; i++) {
*(&this->foo + i) = 0;
}
}
I found related questions here How to iterate through variable members of a class C++, here C++: Iterating through all of an object's members?, here Are class members garaunteed to be contiguous in memory? and here Class contiguous data, with some people suggesting this kind of thing is ok and others a no-no. The latter say there's no guarantee it won't fail, but don't cite any instances of it actually failing. So my question is, does anyone else use this, or has tried and got into trouble?
Or maybe there's a better way? Originally in my application I did actually use an array instead to represent my object, with indices like so:
int i_foo = 0, i_bar = 1, ..., i_barf = 57;
However once I introduced different objects (and arrays thereof) the index naming started to get out of hand. Plus I wanted to learn about classes and I'm hoping some of the other functionality will prove useful down the line ;-)
I use the iteration pretty heavily, e.g. to calculate statistics for collections of objects. Of course I could create a function to map the class members to an array one-by-one, but performance is a priority. I'm developing this application for myself to use on Windows with VS. I would like to keep other platform options open, but it's not something I intend to distribute widely. Thanks
George:
I think you can have a better solution (like a method that will return the i-th attribute:
double get(size_t idx)
{
switch (idx)
{
case 0: return foo;
case 1: return bar;
case 2: return foo_bar;
....
}
}
Using pointer arithmetic to iterate over class data members can cause problems during code optimization. Example:
struct Vec3
{
double x, y, z;
inline Vec3& operator =(const Vec3& that)
{
x = that.x;
y = that.y;
z = that.z;
return *this;
}
inline double& operator [](int index)
{
return (&x)[index];
}
};
...
Vec3 foo = bar; // operator =
double result = foo[2]; // operator []
...
Both operators are inlined, the value of the result depends on the final instructions reordering. Possible cases:
foo.x = bar.x;
foo.y = bar.y;
foo.z = bar.z;
result = (&foo.x)[2]; // correct -- result contains new value
foo.x = bar.x;
foo.y = bar.y;
result = (&foo.x)[2]; // incorrect -- result contains old value
foo.z = bar.z;
foo.x = bar.x;
result = (&foo.x)[2]; // incorrect -- result contains old value
foo.y = bar.y;
foo.z = bar.z;
Some compilers just do not realise that (&foo.x)[2] is the same data as foo.z and they reorder instructions incorrectly. It is very hard to find bugs like this.
I'm working on a problem which requires me to use the STL linked list class to represent a polynomials. I've made a good start on getting the class definition, however I'm a little confused as to where to go next (novice programmer - please excuse my potential ignorance).
class Polynomial
{
public:
Polynomial(); //Default constructor
Polynomial(pair<double,int>); //Specified constructor
void add(Polynomial);
Polynomial multiply(Polynomial);
void print();
private:
list<int> order_terms;
list<double> coeffs;
};
I have two questions:
1) It seems more elegant to store the terms and coefficients as a pair - however I'm unsure how to get that working using the STL list.
2) Regarding the add member function, I'm unsure how to implement it such that I can define a Polynomial and then add terms to it like this:
Polynomial test(pair<3.14,0>);
Polynomial test_2(pair<2,1>);
test.add(test_2);
The main thing I'm having issues with understanding how to access the terms stored in the other object and linking it to the first Polynomial.
Any help greatly appreciated.
EDIT: Code for the add() function - currently not working
void Polynomial::add(const Polynomial& rhs)
{
//Perform some sort of sort here to make sure both lists are correctly sorted
//Traverse the list of terms to see if there's an existing nth order
//term in the list on the left-hand-side polynomial.
list<int>::iterator itr;
list<int>::iterator itl;
for(itr=rhs->terms.begin(); itr!=rhs->terms.end(); itr++)
{
bool match=0;
//See if there's an existing terms, if so add to it
for(itl=terms.begin(); itl!=terms.end(); itl++)
{
if(*itl->second)==*itr->second)
{
*itl->first+=*itr->first;
match = 1;
}
}
//If not, this is the first nth order term so just push it onto the list
if(!match){ terms.push_back(*itr); //Perform the sort again }
}
To use a pair in a list you can do:
list<pair<double, int> > - note the space between the >. It's also nice to do something like
typedef pair<double, int> TermCoeff;
list<TermCoeff> equation;
To sort a list:
list<TermCoeff> equation;
// insert items
equation.sort(coeff_compare);
There are pre-defined comparator functions for a pair in the <utility> header. They compare the first elements and then the second ones if first is equal.
For your second question you should remember that an object of a class can access the member variables of an object of the same class, even if they are private. If you don't leave any gaps in your coefficients (in the constructor fill in missing ones with the second value of the pair set to 0) this means your add method can look like:
Polynomial& Polynomial::add(const Polynomial& rhs) {
// constructor should sort all terms and enforce that all terms are present
// lhs = current object (left hand side of operator)
// rhs = other object (right hand side of operator)
// example: lhs.add(rhs)
list<TermCoeff>::const_iterator rhs_iter = rhs.terms.begin();
list<TermCoeff>::iterator lhs_iter = terms.begin();
while(rhs_iter != rhs.terms.end()) {
if (lhs_iter != terms.end()) {
// add because we aren't at the end of current object's terms
lhs_iter->second += rhs_iter->second;
++lhs_iter;
} else {
// insert because we are at the end of current object's terms
terms.push_back(*rhs_iter);
lhs_iter = terms.end(); // keep the iterator at the end
}
++rhs_iter;
}
return *this;
}
int main (int argc, const char * argv[])
{
list<TermCoeff> first, second;
first.push_back(TermCoeff(0, 0.0)); // empty
first.push_back(TermCoeff(1, 5.0));
first.push_back(TermCoeff(2, 5.0));
second.push_back(TermCoeff(0, 6.0));
second.push_back(TermCoeff(1, 0.0)); // empty
second.push_back(TermCoeff(2, 8.0));
second.push_back(TermCoeff(3, 9.0));
Polynomial first_eq(first);
Polynomial second_eq(second);
first_eq.add(second_eq);
first_eq.print();
return 0;
}
Note that I returned a reference to the current object. This is a nice thing to do in an addition method because then you can chain additions:
first.add(second).add(third);
or
first.add(second.add(third));
Others have explained list<pair<double, int> > (and I like shelleybutterfly's suggestion to derive Polynomial from the list, except that I'd make it protected, not public, so that outside code is not too free to mess with the contents of the list).
But the add function is a little tricky, because adding two polynomials doesn't generally mean concatenating them or adding their terms together. The operation is actually more like merging-- and you'll soon see that the lists must be sorted. (In fact, it's more natural to represent polynomials as vectors, but I guess that's not the assignment.)
I suggest you implement Polynomial::add(pair<double, int>), first, then implement the other one (add(Polynomial &)) in terms of that.
I don't want to spell it out too much, since this looks like homework. Is this enough to point you in the right direction?
EDIT:
Your new code looks correct (albeit inefficient) if you fix a couple of bugs:
void Polynomial::add(const Polynomial& rhs)
{
// Don't forget to implement the sorting routine.
// The iterators must be of the correct type. And itr must be const,
// since you have declared rhs to be a const reference. The compiler
// will not allow you to have an iterator with the power to alter
// a const thing.
list<pair<double,int> >::const_iterator itr;
list<pair<double,int> >::iterator itl;
for(itr=rhs->terms.begin(); itr!=rhs->terms.end(); itr++)
{
bool match=false;
for(itl=terms.begin(); itl!=terms.end(); itl++)
{
// You have an extra parenthesis here, and too much dereferencing.
if(itl->second == itr->second)
{
itl->first+=itr->first;
match = true;
}
}
if(!match)
{ terms.push_back(*itr); //Perform the sort again
} // Be careful not to catch the closing brace in a comment
}
}
Once it is working, you can think about ways to make it cleaner and more efficient. For example, if you insert the new term in the right place, the list will always be in the right order and there will be no need for a sort routine.
As for using a pair, why not use a list<pair<double, int>> (list< pair<double, int> > for older compilers)? Or you could even define a separate class to hold your pair like so:
// example is implemented inline, you could always pull it out to
// your source file; although it's even possible that you could
// do everything inline if you want to allow just including a
// header but not having to link a separate file.
class CoeffAndTerm : public pair<double,int>
{
public:
// if you need it you should put extra functions here to
// provide abstractions:
double getTotalValue()
{
return first * second;
}
}
and then use
list<CoeffAndTerm> Polynomial;
as your variable, or even
// same stuff goes for this class RE: the inline function definitions
class Polynomial : public list<CoeffAndTerm>
{
public:
// same goes here for the abstraction stuff maybe things
// like in your current Polynomial class; assuming some
// functions here ...
Polynomial Multiply(Polynomial other)
{
Polynomial Result = new Polynomial();
for (int i=0; i < size(); ++i)
{
Result.addCoeffAndTerm(
new CoeffAndTerm(
other.first * first,
other.second * second
);
}
return Result;
}
}
so that you've got Polynomial being a derivation of the list itself. Not sure the exact usage of the Polynomial, so it's hard for me to speak to which makes more sense, but I like this way better as a general rule for a type such as this; seems to be that the polynomial "is a" list of coefficient and terms, it doesn't just "have" one. :) I'm sure that's debatable, and again it depends on the actual usage of your code.
for the operations, you could do reference returns, as in one of the other examples, but I have implemented the multiply without modifying the existing value, which you could also do for Add, Subtract, etc. so, assuming First, Second, Third, etc. are other polynomials
Polynomial Result = First.Multiply(Second).Add(Third).Subtract(Fourth);
you could also implement copy constructor, operator =, operator +, operator *, operator / and then do things that look like normal math:
Polynomial Result = First * Second + Third - Fourth;
While it's possible to use std::pair to group the term order and coefficient, I would recomment against it: it's not very readable - it's not clear what 'first' and 'second' means, and C++ will implicitly cast between numeric types - and you get no benefit from the added functionality of pair (ordering).
Instead, create a class like:
class Term {
double coeff_;
int exp_;
public:
Term(double coeff, int exp): coeff_(coeff), exp_(exp) {}
double coefficient() const { return coeff; }
int exponent() const { return exp; }
[...]
};
class Polynomial {
std::list<Term> terms;
[...]
Making fields public (e.g. by using struct or publicly deriving from pair) for performance reasons is not a good idea: inline constructor, getters and setters are just as fast as reading or writing the variable directly, and they have the advantage of encapsulating the implementation.
For that matter, you may want to create separate types to wrap polynomial coefficients and exponents themselves, in order to avoid mixing up numeric types, and performing nonsensical operations e.g.:
class Coefficient {
double val;
public:
explicit Coefficient(double value): val(value) {}
double getValue() { return val; }
double operator*(double rhs) { return val*rhs; }
Coefficient operator+(const Coefficient& rhs) {
return Coefficient(val+rhs.val);
}
[...]
};
etc.
Another possibility: instead of using a class, you could make as struct to represent the term and coefficient; you still can define methods on it just like a class, but the members are public by default which may make sense for efficiency reasons, especially if you're doing a lot of processing with these things. So, maybe:
struct CoeffAndTerm
{
int Term;
double Coeff;
private CoeffAndTerm(int parTerm, double parCoeff)
{
Term = parTerm;
Coeff = parCoeff;
}
public static CoeffAndTerm Make(int parTerm, double parCoeff)
{
return new CoeffAndTerm(parTerm, parCoeff);
}
// etc. and otherwise you can just do things as given in the example
// with the classes deriving from list<pair<int, double>>, e.g.,
// silly example again
public double getTotalValue()
{
return first * second;
}
}
and same applies otherwise as in the first example, again giving more direct access than that example had, but still allowing for the abstraction methods to be placed directly on the object
struct Polynomial : public list<CoeffAndTerm>
{
list<CoeffAndTerm> CoefficientsAndTerms;
Polynomial Multiply(Polynomial other)
{
Polynomial Result = new Polynomial();
for (int i=0; i < size(); ++i)
{
Result.addCoeffAndTerm(
new CoeffAndTerm(
other.first * first,
other.second * second
);
}
return Result;
}
// etc.
}