C++ Intertwined #includes - c++

First, I am a beginner in C++. Second, I'm sorry of this post turns out to be too long. I have a few classes that make use of each other, similar to this picture (a quick sketch):
And this is a quick sketch of a usable code. The formulas are bogus, but the functionality is close to the real problem. I omitted making source files for simplicity. The #includes are as they were after the last compile that got me the fewest errors...
"y.h"
#pragma once
#include "a.h"
#include "b.h"
class X;
class A;
class B;
class Y
{
private:
double m_y;
public:
Y(double b, double c):
{
if (c)
m_y = b*b;
else
m_y = sqrt(b);
if (b<0)
{
A::setP(m_y);
A::setQ(m_y + 1);
A::setR(m_y - 1);
}
else
{
B::setP(m_y);
B::setQ(m_y + 1);
B::setR(m_y - 1);
}
}
"a.h"
#pragma once
#include "x.h"
class X;
class A : virtual public X
{
private:
double m_p, m_q, m_r;
public:
A(double a, double b): m_p {a*a}
{
m_q = m_p + 0.5 * b;
m_r = m_q - m_p;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
"b.h"
#pragma once
#include "x.h"
class X;
class B : virtual public X
{
private:
double m_p, m_q, m_r;
public:
B(double a, double b): m_p {a + a}
{
m_q = m_p*m_p;
m_r = b + m_q;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
"x.h"
//#include "a.h"
class A;
class B;
class X
{
private:
double m_x1, m_x2;
public:
X(double a, double b, double c, int d): m_x1 {2*a}
{
double p, q, r;
switch (d)
{
case 1:
p = A::getP();
q = A::getQ();
r = A::getR();
m_x2 = p * b + q * c - r;
break;
case 2:
p = B::getP();
q = B::getQ();
r = B::getR();
m_x2 = (p - q) * b + r / c;
break;
}
}
double getX1() { return m_x1; }
double getX2() { return m_x2; }
};
"main.cpp"
#include "x.h"
#include <iostream>
int main()
{
X test {3.14, 0.618, 1.618, 1};
std::cout << test.getX1() << '\t' << test.getX2() << '\n';
return 0;
}
My problem is with the necessary includes (assume each class has a header and source file). For now, let's consider only class A in there. main.cpp only has #include x.h. To avoid repeating the code with all combinations, I'll try ennumerating what I did, so far:
#include a.h in class X, then #include y.h in class A, class Y has no #include, no forward declarations. The compiler complains about expected class name before { in both Y and A.
add forward declarations to the above => invalid use of incomplete type "class ..." in both Y and A.
do it backwards with #include a.h in class Y, then #include x.h in class A, class X has no #include, with forward declarations => incomplete type A used in nested name spacifier in class X, pointing at X(): { int x {A::funcA()} }.
as above and no forward declarations means errors everywhere.
Searches on the net said this happens because of cyclic dependencies, but how can that be since I am only including the previous or the next, never both? There were answers saying that using #pragma once instead of the usual may resolve the problems, I tried, it's the same incomplete type.... For reference only, I also tried looking at a few source codes (wxMaxima, audacious) to see how they did it, and it seems they used my first approach.
At this point, I am very confused. If the above can be used for an answer, can someone please give me some directions on how to properly use the #includes here? If not, please leave a comment and I'll delete this, if needed.

Related

'B::operator A' uses undefined class 'A'

I have found the following example in one of my C++ courses. When I try to compile it I get the following error:
'B::operator A' uses undefined class 'A'
Why does it say that class A is undefined?
#include<iostream>
using namespace std;
class A;
class B
{
int x;
public: B(int i = 107) { x = i; }
operator A();
};
B::operator A() { return x; }
class A
{
int x;
public: A(int i = 6) { x = i; }
int get_x() { return x; }
};
int main()
{
B b;
A a = b;
cout << a.get_x();
system("Pause");
}
The compiler needs to know what A is here:
B::operator A() { return x; }
But you only have a forward declaration. You need to move the declaration of class A above B
You are only allowed to use pointers to or references of incomplete types which is what have when you forward declare a type
You need to declare A above B, so that the definition of A is visible to B.
#include<iostream>
using namespace std;
class A
{
int x;
public: A(int i = 6) { x = i; }
int get_x() { return x; }
};
class B
{
int x;
public: B(int i = 107) { x = i; }
operator A();
};
B::operator A() { return x; }
int main()
{
B b;
A a = b;
cout << a.get_x();
}
This should work.

c++ linking error in example program

I am trying out some c++, and as an introduction to classes, I tried to program a triangle(driehoek.cpp) with points(punt.cpp). For now, my main does nothing, but I am getting the following linking error:
Undefined symbols for architecture x86_64:
"punt::punt()", referenced from:
driehoek::driehoek(punt&, punt&, punt&) in driehoek.o
___cxx_global_var_init in driehoek.o
___cxx_global_var_init1 in driehoek.o
___cxx_global_var_init2 in driehoek.o
ld: symbol(s) not found for architecture x86_64
here are the files i use for this project:
driehoek.h:
#ifndef DRIEHOEK_H
#define DRIEHOEK_H
#include "punt.h"
class driehoek {
public:
driehoek();
driehoek(punt &a, punt &b, punt &c);
driehoek(const driehoek& orig);
virtual ~driehoek();
void setA(punt &a);
void setB(punt &b);
void setC(punt &c);
void print();
punt getA();
punt getB();
punt getC();
private:
punt a;
punt b;
punt c;
};
#endif /* DRIEHOEK_H */
driehoek.cpp:
#include "driehoek.h"
#include <iostream>
punt a;
punt b;
punt c;
driehoek::driehoek(punt::punt &a, punt::punt &b, punt::punt &c) {
this->a = a;
this->b = b;
this->c = c;
}
driehoek::~driehoek() {
delete this;
}
void setA(punt &pu){
a = pu;
}
void setB(punt &pu){
b = pu;
}
void setC(punt &pu){
c = pu;
}
void driehoek::print(){
std::cout << "pA = " << &a << " pB=" << &b << " pC";
}
punt.h:
#ifndef PUNT_H
#define PUNT_H
class punt {
public:
punt();
punt(int x, int y);
punt(const punt& orig);
virtual ~punt();
void setX(int x);
void setY(int y);
int getX();
int getY();
float distance(punt pu);
private:
int x;
int y;
};
#endif /* PUNT_H */
punt.cpp:
#include <math.h>
#include "punt.h"
int x;
int y;
punt::punt(int x, int y) {
this->x = x;
this->y = y;
}
punt::~punt() {
delete &y;
delete &x;
delete this;
}
void punt::setX(int x){
this->x = x;
}
void punt::setY(int y) {
this->y = y;
}
int punt::getX() {
return this->x;
}
int punt::getY() {
return this->y;
}
float punt::distance(punt pu){
return
sqrt(
((this->x - pu.x) * (this->x - pu.x))
+
((this->y - pu.y) * (this->y - pu.y))
);
}
And for completeness, main.cpp:
#include <cstdlib>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
return 0;
}
I am sure that the same question has already be asked by someone else, but after searching for a while I couldn't find any answers that I understood. My apologies if this turns out to be a duplicate.
The default constructor, punt::punt(), is needed for creating the three non-member variables you added in "driehoek.cpp".
You're getting the error in question because you declared that constructor but you never defined it.
(There are a couple of unnecessary variables in "punt.cpp", too.)
Change your constructor definition as like as below,
driehoek::driehoek(punt &a, punt &b, punt &c) {
this->a = a;
this->b = b;
this->c = c;
}
The declared constructor and its definition doesn't match for your class "driehoek" .

Abstracting a call to combine the results of a vector of classes

I've got a class which acts as a combiner of a vector of pointers to an abstract base class. In the combined class there is a lot of repetition of the function that is used to combine the member functions together, e.g.
class Base {
public:
virtual double foo1(double x) = 0;
virtual double foo2(double x) = 0;
};
class Combined : public Base {
std::vector< std::shared_ptr<Base> > bases;
public:
double foo1(double x) {
double rv = 0.0;
for( auto& b : bases ) {
rv += b->foo1(x);
}
return rv;
}
double foo2(double x) {
double rv = 0.0;
for( auto& b : bases ) {
rv += b->foo2(x);
}
return rv;
}
};
It feels like I should be able to write one function to abstract that pattern away from having to repeat it for every method, so the Combined could be written in a way such as
class Combined : public Base {
std::vector< std::shared_ptr<Base> > bases;
public:
double foo1(double x) {
return combiner(foo1, x);
}
double foo2(double x) {
return combiner(foo2, x);
}
};
and there would be a combiner function along the lines of
double combiner(FuncName f, double x)
{
double rv = 0.0;
for( auto& b : bases ) {
rv += b->f(x);
}
return rv;
}
To reduce the quantity of boilerplate
Any help would be greatly appreciated.
It's called std::accumulate (found in <numeric>) and it can do exactly this.
#include <iostream>
#include <memory>
#include <algorithm>
using namespace std;
struct iFoo {virtual double foo() const=0;};
struct A : public iFoo {virtual double foo() const{return 10;}};
struct B : public iFoo {virtual double foo() const{return 20;}};
std::vector<std::unique_ptr<iFoo>> foos;//pretend its a member variable i'm lazy
//pretend its a member function (again, lazy)
template <typename T,typename K>
T xform_accumulate(T init,K xformer)
{
return std::accumulate(foos.cbegin(),foos.cend(),init,[xformer](T a,const std::unique_ptr<iFoo>& b) {return a+xformer(b);});
}
int main()
{
foos.push_back(std::unique_ptr<iFoo>(new A()));
foos.push_back(std::unique_ptr<iFoo>(new B()));
double x = xform_accumulate( 0.0, [](const std::unique_ptr<iFoo>& x){return x->foo();});
cout << "Hello World" << x << endl;
return 0;
}

C++ Passing a function to a function using functors

I have two functors:
class SFunctor {
public:
SFunctor(double a) { _a = a; }
double operator() (double t) { return _a * sin(t); }
private:
double _a;
};
class CFunctor {
public:
CFunctor(double b) { _b = b; }
double operator() (double t) { return _b * cos(t); }
private:
double _b;
};
I want to pass one or the other of these functions to another function:
double squarer(double x, ??______?? func) {
double y = func(x);
return y * y;
}
In my main program I want to make a call like this:
CFunctor sine(2.);
SFunctor cosine(4.);
double x= 0.5;
double s = squarer(x, sine);
double c = squarer(x, cosine);
How do I specify the function fund, that is what goes in front of it in place of ??_?? ?
You can simply do it with templates
template <class F>
double squarer(double x, F& func) {
double y = func(x);
return y * y;
}
I'm not knocking on the above template answer. In fact, it may be the better choice of the two, but I wanted to point out that this can be done with polymorphism as well. For example...
#include <math.h>
#include <iostream>
using std::cout;
using std::endl;
class BaseFunctor {
public:
virtual double operator() (double t) = 0;
protected:
BaseFunc() {}
};
class SFunctor : public BaseFunctor {
public:
SFunctor(double a) { _a = a; }
double operator() (double t) { return _a * sin(t); }
private:
double _a;
};
class CFunctor : public BaseFunctor {
public:
CFunctor(double b) { _b = b; }
double operator() (double t) { return _b * cos(t); }
private:
double _b;
};
double squarer(double x, BaseFunctor& func) {
double y = func(x);
return y * y;
}
int main() {
SFunctor sine(.2);
CFunctor cosine(.4);
double x = .5;
cout << squarer(x,sine) << endl;
cout << squarer(x,cosine) << endl;
}
I ensured that this was a full working demo, so you can just copy it to test it. You will indeed observe two different numbers print to the terminal, thus proving that polymorphism can be used with functors. Again, I'm not saying this is better than the template answer, I just wanted to point out that it isn't the only answer. Even though the question has been answered, I hope this helps inform anyone who wants to be informed.

C++ class methods

I am learning C++ and I have a question.
I made a class in Netbeans, which made Rectangle.h and Rectangle.cpp. I am trying to add methods that output the Area and Perimeter of the rectangle's l and w variables. I don't know how to create methods in a class and how to incorporate them in the Rectangle.h file.
Here's what I'm trying to do:
Rectangle rct;
rct.l = 7;
rct.w = 4;
cout << "Area is " << rct.Area() << endl;
cout << "Perim is " << rct.Perim() << endl;
Can someone explain how to do this? I'm so confused.
Thanks,
Lucas
In the .h file you have the class definition, where you write down the member variables en member functions (generally as prototype)
In the .cpp file you declare the methods body. Example:
rectangle.h:
class rectangle
{
public:
// Variables (btw public member variables are not a good
// practice, you should set them as private and access them
// via accessor methods, that is what encapsulation is)
double l;
double w;
// constructor
rectangle();
// Methods
double area();
double perim();
};
rectangle.cpp:
#include "rectangle.h" // You include the class description
// Contructor
rectangle::rectangle()
{
this->l = 0;
this->w = 0;
}
// Methods
double rectangle::area()
{
return this->w * this->l;
}
double rectangle::perim()
{
return 2*this->w + 2*this->l;
}
But like gmannickg said you should read a book about c++ or a real tutorial, that will explain you how the syntax works. And Object Oriented Programming (if you are not familiar with it)
Quite easy - this is just an example and one possible implementation. Note that the following adds some additional stuff (like const and a constructor) you don't necessarily need; depending on your useage.
class Rectangle {
private:
double l, w;
// This constructor has optional arguments, meaning you can skip them (which will result in them being set to 0).
public:
Rectangle(const double l = 0, const double w = 0);
double Area(void) const; // the const keyword after the parameter list tells the compiler that this method won't modify the actual object
double Perim(void) const;
}
Rectangle::Rectangle(const double _l, const double _w) : l(_l), w(_w) { // this is an initializer list - as an alternative, here it would be possible to just assign the values inside the function body
}
double Rectangle::Area(void) const {
return l * w;
}
double Rectangle::Perim(void) const {
return l + l + w + w;
}
The header (.h) file is mainly concerned with specifying the interface. While you can implement functions there as well, you typically do not. Instead, you define the class in the header, and then implement it in the .cpp (.hpp, whatever) file. For example, your rectangle class:
// Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
public:
// constructors, just initialize our private members
Rectangle(int x, int y, int w, int h)
: _x(x), _y(y), _w(w), _h(h) { }
Rectangle() : _x(0), _y(0), _w(0), _h(0) { }
// implement these in Rectangle.cpp
int get_x();
void set_x(int x);
int get_y();
void set_y(int y);
int get_width();
void set_width(int w);
int get_height();
void set_height(int h);
int Area();
int Perim();
private:
int _x, _y, _w, _h;
};
#endif
// Rectangle.cpp
#include "Rectangle.h"
#include <algorithm>
using std::max;
int Rectangle::get_x() {
return _x;
}
void Rectangle::set_x(int x) {
_x = x;
}
int Rectangle::get_y() {
return _y;
}
void Rectangle::set_y(int y) {
_y = y;
}
int Rectangle::get_width() {
return _w;
}
void Rectangle::set_width(int w) {
_w = max(w, 0);
}
int Rectangle::get_height() {
return _h;
}
void Rectangle::set_height(int h) {
_h = max(h, 0);
}
int Rectangle::Area() {
return _w * _h;
}
int Rectangle::Perim() {
return _w * 2 + _h * 2;
}