c++ linking error in example program - c++

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" .

Related

How to code operation overload so it operates to a specific class member such as A<<{{1,2,3},{5,6,7}} in c++?

You can redefine operator << in class by overload it.
However, how do you code it so that it would operates specific to a certain class member?
for example
class C
{
int a;
double b;
}
// I would like something like
void main ()
{
C c;
c.a << 1; // sets class member a to value 1;
}
I want a operator defined in Class C that operates specifically to class member a.
a pesudo-code would be
class C
{
int a;
double b;
void operator << (istream & fin)
{
... fin.get()... some code
}
}
Stating the obvious for a moment, assuming the variable is public, you'd use:
class C
{
int a;
double b;
}
// I would like something like
void main ()
{
C c;
c.a = 1; // sets class member a to value 1;
}
The << and >> operators are bit shifts, which have their own meaning. Overloading those for your own purpose is probably a bad idea.
The C++ way of doing things is to avoid setting member variables externally where possible (e.g. using RAII approaches, to set data at initialisation)....
class C
{
public:
C(int a, double b) : a(a), b(b) {}
int getA() const { return a; }
double getB() const { return b; }
private:
int a;
double b;
};
.... Or by adding a setter method if you really need it, e.g.
class C
{
public:
C(int a, double b) : a(a), b(b) {}
int getA() const { return a; }
double getB() const { return b; }
void setA(int v) { a = v; }
void setB(double v) { b = v; }
private:
int a;
double b;
};
You could in theory generate a new type, and overload the operators for that type, but it's not something I'd recommend (because changing the meaning of an operator is almost always a bad idea)
struct MyIntType {
int i;
// overload cast operator
operator int () {
return i;
}
// assign
MyIntType& operator = (const int& v) {
i = v;
return *this;
}
// not recommended :(
MyIntType& operator << (const int& v) {
i = v;
return *this;
}
};
class C
{
public:
MyIntType a;
double b;
};
void main ()
{
C c;
c.a << 1;
}
Having read your comment above, it sounds like you want to do this:
class C
{
public:
// I'm still not recommending this :(
C& operator << (const int& v) {
a = v;
return *this;
}
private:
int a;
double b;
};
void main ()
{
C c;
c << 1; //< now sets c.a
}

Can't use `cout` with a class even if I overloaded `operator<<`

Title says all. I overloaded the operator<< as everyone on the internet said to, but I still got that stupid error for an invalid operator. What have I done wrong? Here's my code:
#include <iostream>
#include <cstdio>
using namespace std;
class Calc {
private:
union _Print_Datatypes {
int I;
double D;
string S;
char C;
};
public:
int i;
void Sum(long double _a, long double _b) {
return _a + _b;
}
void Sub(long double _a, long double _b) {
return _a - _b;
}
void Div(long double _a, long double _b) {
return _a / _b;
}
void Mult(long double _a, long double _b) {
return _a * _b;
}
};
std::ostream &operator<<(std::ostream &os, Calc const &m) {
return os << m.i;
}
int main() {
Calc _calc;
cout << _calc.Sum(2,2);
}
cout << _calc.Sum(2,2);
The return type from your Sum() method is a void. Obviously, operator<< does not work on voids.
You need to change your Sum(), et al, to return Calc &, and have them return *this.
Your code doesn't compile even without the <<:
main.cpp:17:9: error: void function 'Sum' should not return a value [-Wreturn-type]
return _a + _b;
^ ~~~~~~~
Your functions are declared to return void.

C++ Intertwined #includes

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.

'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++: Calling member function via pointer

I have this example code of using pointer to member function, which I want to change during runtime, but I cannot make it work. I've already tried this->*_currentPtr(4,5) (*this)._currentPtr(4, 5). What is the proper way of calling pointer to method inside same class ?
The error : expression must have (pointer-to-) function type
#include <iostream>
#include <cstdlib>
class A {
public:
void setPtr(int v);
void useFoo();
private:
typedef int (A::*fooPtr)(int a, int b);
fooPtr _currentPtr;
int foo1(int a, int b);
int foo2(int a, int b);
};
void A::setPtr(int v){
if(v == 1){
_currentPtr = foo1;
} else {
_currentPtr = foo2;
}
}
void A::useFoo(){
//std::cout << this->*_currentPtr(4,5); // ERROR
}
int A::foo1(int a, int b){
return a - b;
}
int A::foo2(int a, int b){
return a + b;
}
int main(){
A obj;
obj.setPtr(1);
obj.useFoo();
return 0;
}
You need to tell the compiler which class the foos are coming from (otherwise it thinks they're functions from global scope):
void A::setPtr(int v){
if(v == 1){
_currentPtr = &A::foo1;
// ^^^^
} else {
_currentPtr = &A::foo2;
// ^^^^
}
}
and you need a set of parentheses here:
std::cout << (this->*_currentPtr)(4,5);
// ^ ^