Nested classes error in C++ - c++

I'm self-learning C++ as a beginner, and I faced some problems regarding Nested Classes. I was trying to define a class for a quadrangle given four vertices (define a point called vertices), which
is represented by an object of a nested class for two-dimensional points. I only use one point to test my answer. My answer to the question is:
#include <iostream>
#include <assert.h>
using namespace std;
class quadrangle
{
public:
class vertex
{
private:
public:
int x, y;
friend class quadrangle;
vertex();
vertex(int a, int b);
vertex(const vertex & old);
};
vertex p1;
int a, b;
friend class vertex;
quadrangle();
quadrangle(vertex(int a, int b)) : p1(a,b) {};
quadrangle(const quadrangle & old);
void draw();
};
quadrangle::vertex::vertex()
{
x = 0; y = 0;
}
quadrangle::vertex::vertex(int a, int b)
{
x = a; y = b;
}
void quadrangle::draw()
{
cout << "p1: (" << p1.x << "," << p1.y << ") " << endl;
}
quadrangle::quadrangle()
{
p1.x = 0; p1.y = 0;
}
int main()
{
quadrangle q1(quadrangle::vertex(2,3));
q1.draw();
}
Somehow I just got
error: no matching function for call to
'quadrangle::quadrangle(quadrangle::vertex)'
and have stuck for a whole afternoon. Could someone explain what's wrong in my code?? I know something's wrong with my constructor but I just couldn't fix it...

Following is not what you expect:
quadrangle(vertex(int a, int b)) : p1(a,b) {};
it is a constructor which take a function returning vertex and taking 2 int.
and then you initialize member vertex p1 with uninitilized member a and b.
What you want is simply:
quadrangle(const vertex& v) : p1(v) {}
(And remove members a, b).

Your error tell it all, you dont have constructor:
quadrangle(const vertex & old);
and it is required to make this initialization:
quadrangle q1(quadrangle::vertex(2,3));
And this is really strange:
quadrangle(vertex(int a, int b)) : p1(a,b) { }
it looks like its a constructor taking a function prototype (or a function type?) - but its not a function pointer I guess. p1(a,b) compiles only because you have such variables in your class.
[edit]
after comment from Quentin - above declaration is a function pointer
Function types in a function parameters' declaration decay to pointers
below example shows various ways you can write function pointer as parameter to function:
std::string bar(int a, int b) {
std::cout << "bar";
return "";
}
void foo1(std::string(int a, int b)) { } // Unnamed function pointer
void foo2(std::string(pf)(int a, int b)) { pf(0,0); } // Named function pointer
void foo3(std::string(*pf)(int a, int b)) { pf(0,0);} // Named function pointer
int main() {
foo1(bar);
foo2(bar);
foo3(bar);
}

Related

composition of classes in c++

This is an example of the composition of classes. But my code doesn't show a correct answer. This program must calculate the length of the line segment in the coordinates of the two ends of the line segment!
I don't know what to do in the main function. this code consists of two classes.
#include <cmath>
#include <iostream>
using namespace std;
class point {
private:
float x;
float y;
public:
void setpoint(float abscissa, float ordinate) {
x = abscissa;
y = ordinate;
}
float getx() { return x; }
float gety() { return y; }
};
class LineSegment {
public:
float length() {
result = sqrt(pow(a.getx() - b.getx(), 2) + pow(a.gety() - b.gety(), 2));
return result;
}
void displayMessage() { cout << result; }
private:
float result;
point a;
point b;
};
int main() {
point a;
float q, s;
cout << "Enter two numbers for first point:\n";
cin >> q >> s;
a.setpoint(q, s);
point b;
float e, r;
cout << "Enter two numbers for second point:\n";
cin >> e >> r;
a.getx();
a.gety();
LineSegment pt;
pt.length();
pt.displayMessage();
return 0;
}
enter image description here
The a and b local variables of your main() function are unrelated to the a and b members of class LineSegment. You should give LineSegment a constructor by which you can convey the endpoints to it, or at minimum provide a method or methods by which the endpoints can be set after the fact. You must not attempt to compute the segment length before its endpoints are set.
Neither the member a nor the member b are initialized for pt. You need to initialize them or they are initialized using the default constructor of point which happens to not do any initialization resulting in undefined behavior.
You could e.g. pass the points to the constructor of LineSegment to fix this:
class LineSegment {
public:
LineSegment(const point& p1, const point& p2)
: a(p1), b(p2)
{}
...
};
...
LineSegment pt {a, b};
...
Note: I recommend adding a prefix to member variables. m_ is one option (i.e. you'd use m_a and m_b as member variable names). This way you avoid confusion like this and also avoid shadowing of variables assuming this is the only kind of variable using this prefix.
Edit: You also never call setpoint on b in main; you need to do this before passing the points to the constructor in the above snippet.
Here is your code, touched up to work:
#include <cmath>
#include <iostream>
// using namespace std; // CHANGED: Bad practice
class point {
private:
float x = 0.0f; // CHANGED: Add default member initialization
float y = 0.0f;
public:
point() = default; // CHANGED: Add default constructor
point(int abscissa, int ordinate) : x(abscissa), y(ordinate) {} // ADDED
void setpoint(float abscissa, float ordinate) {
x = abscissa;
y = ordinate;
}
float getx() const { return x; } // CHANGED: Mark getters as const
float gety() const { return y; }
};
class LineSegment {
public:
// CHANGED: Add constructor so you can actually build a LineSegment
LineSegment(point one, point two) : a(one), b(two) {}
// CHANGED: Made a one-liner
float length() const {
return sqrt(pow(a.getx() - b.getx(), 2) + pow(a.gety() - b.gety(), 2));
}
// void displayMessage() const { std::cout << result; } // CHANGED: Not
// needed
private:
// float result; // CHANGED: Does not need to stored
point a;
point b;
};
int main() {
float q, s;
std::cout << "Enter two numbers for first point:\n";
std::cin >> q >> s;
point a(q, s); // Can now directly initialize
float e, r;
std::cout << "Enter two numbers for second point:\n";
std::cin >> e >> r;
point b(e, r); // CHANGED: Actually put values into b
// a.getx(); // CHANGED: These do nothing
// a.gety();
LineSegment pt(a, b); // CHANGED: Actually put data into pt
std::cout << "\nLine Length: " << pt.length() << '\n'; // CHANGED: Make use
// of functions now
// available
return 0;
}
Your biggest issues were not initializing your objects correctly. point b was never given the values e and r, and LineSegment pt was never given any points.
Making those small changes and your code works as expected. Just using a simple example of (0, 0) and (1, 1) provides output of 1.41421, which is root-2, which is correct.

Can't assign array element to class variable while overloading "=" operator

I am quite new in C++ programming, so maybe that's why I can't figure out why this assignment is not working.
In my class, I want to overload "=" operator.
I have specified a function, that outputs variables as an array. In overloading, I want to assign those variables to new object.
obj_new = obj_with_variables
overloading:
obj_new_x=obj_with_values_parameters()[0];
obj_new_y=obj_with_values_parameters()[1];
Here is a code:
// Test1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "string"
using namespace std;
class Vector2D
{
public:
Vector2D()
{
}
Vector2D(int& a, int& b)
:x(a), y(b)
{
}
void Drukuj()
{
cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int&a, int&b)
{
x = a;
y = b;
}
int* Wspolrzedne()
{
int tab[2] = { x,y };
return tab;
}
void operator = (Vector2D& obj)
{
int* a = obj.Wspolrzedne();
cout << a[0] << "\n";
x = a[0];
cout << x << " what? \n";
y = a[1];
}
private:
int x, y;
};
int main()
{
int x1 = 2, x2 = 3;
Vector2D wektor(x1, x2);
wektor.Drukuj();
Vector2D wektor2;
wektor2 = wektor;
wektor2.Drukuj();
wektor.Drukuj();
return 0;
}
The problem is that it assigns some strange values. However, if I don't use a reference, but declare 2 int values (j,k) and assign array element to them [0,1], it works fine.
Also, when using static numbers (for example, instead of a[0] ; use "2") it works fine too.
What is going on?
I would be glad if somebody could point me to right answer/ resources.
Regards,
In your member function int* Wspolrzedne(), you return the address of local variable tab. Accessing this variable once its life time has ended, as you do in your = operator, is undefined behaviour.
Your code has undefined behavior because operator= is accessing invalid data. Wspolrzedne() is returning a pointer to a local variable tab that goes out of scope when Wspolrzedne() exits, thus the a pointer used in operator= is not pointing at valid data.
If you want Wspolrzedne() to return multiple values, you need to have it return (by value) an instance of a struct or class to hold them. Try something more like this:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct Coordinate {
int x;
int y;
};
class Vector2D
{
public:
Vector2D()
: x(0), y(0)
{
}
Vector2D(int a, int b)
: x(a), y(b)
{
}
Vector2D(const Coordinate &c)
: x(c.x), y(c.y)
{
}
Vector2D(const Vector2D &src)
: x(src.x), y(src.y)
{
}
void Drukuj()
{
cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int a, int b)
{
x = a;
y = b;
}
void Wspolrzedne(const Coordinate &c)
{
x = c.x;
y = c.y;
}
Coordinate Wspolrzedne()
{
Coordinate c = { x, y };
return c;
}
Vector2D& operator=(const Vector2D &obj)
{
Coordinate c = obj.Wspolrzedne();
cout << c.x << ',' << c.y << "\n";
Wspolrzedne(c);
return *this;
}
private:
int x;
int y;
};
On the other hand, there is no real reason to even have operator= call Wspolrzedne() to get the coordinates at all, when it can just access obj.x and obj.y directly instead:
Vector2D& operator=(const Vector2D &obj)
{
x = obj.x;
y = obj.y;
return *this;
}
In which case, you can simply eliminate your operator= altogether, and let the compiler provide a default-generated implementation that does the exact same thing for you.
Your interface is dangerous, as returning raw pointers from functions means the caller must know how to manage it. That is, the caller needs to be astutely aware of the answers to questions like, "should the caller delete the pointer or does the object I got it from retain ownership?" What is this pointer pointing to? If it's an array, now many elements are there? If I must delete it, do I use delete or delete[]?
And so on. This is not good because it's very, very error prone.
Next you have a function that returns a pointer to stack-local data. When the function returns, that memory is already invalid so the return value is always going to result in undefined behavior to read.
int* Wspolrzedne()
{
int tab[2] = { x,y };
return tab; // BAD - returns pointer to function stack data
}
Where does tab live? It's destroyed when the function exits, but you're returning a pointer to it.
This is a dangerous interface and should be changed. Perhaps you should return the values as a pair:
std::pair<int, int> Wspolrzedne()
{
return std::pair{ x,y }; // assuming c++17
// return std::pair<int, int>{x, y}; // older compilers
}
An interface like this avoids pointers, and removes all the issues mentioned above.

Do not use class member function inside class

I want to write an object-oriented wrapper around old C-style functions, while keeping the actual function names the same. Take a look at an example:
#include <iostream>
void doStuff(int a, float b)
{
std::cout << "a = " << a << ", b = " << b << "\n";
}
class Stuff
{
private:
int a;
float b;
public:
Stuff(int newA, float newB) : a(newA), b(newB) { }
int getA() { return a; }
float getB() { return b; }
};
class Widget
{
public:
void doStuff(Stuff s)
{
doStuff(s.getA(), s.getB()); //error: no matching function for call to 'Widget::doStuff(int, float)'
}
};
int main()
{
Widget w;
w.doStuff(Stuff(42, 3.14f));
return 0;
}
In this example, void doStuff(int a, float b) is the old C-function. Because in my real code, its equivalent is in an external library/header file, I cannot change its name. Next, Stuff is a container for keeping the values void doStuff(int a, float b) needs. The important things happen in Widget: void Widget::doStuff(Stuff s) should be the actual wrapper. I now expect doStuff(s.getA(), s.getB()) to call the old C-style function void doStuff(int a, int b) but the compilation fails with the given error.
Is it possible to make this code work without changing the name of the both doStuff functions? One option I already thought of is surrounding void doStuff(int a, float b) by some namespace. This works, but seems like very bad practice to me.
My compiler is mingw-w64 with g++ 5.2.0, so C++11 and C++14 are available.
The doStuff(Stuff s) method in your class hides the global function doStuff(int a, float b). If you want to call the global doStuff function, you have to use the scope resolution operator :: (::doStuff(s.getA(), s.getB());)
Try making your call like this:
::doStuff(s.getA(), s.getB());

C++ Passing pointer to non-static member function

Hi everyone :) I have a problem with function pointers
My 'callback' function arguments are:
1) a function like this: int(*fx)(int,int)
2) an int variable: int a
3) another int: int b
Well, the problem is that the function I want to pass to 'callback' is a non-static function member :( and there are lots of problems
If someone smarter than me have some time to spent, he can look my code :)
#include <iostream>
using namespace std;
class A{
private:
int x;
public:
A(int elem){
x = elem;
}
static int add(int a, int b){
return a + b;
}
int sub(int a, int b){
return x - (a + b);
}
};
void callback( int(*fx)(int, int), int a, int b)
{
cout << "Value of the callback: " << fx(a, b) << endl;
}
int main()
{
A obj(5);
//PASSING A POINTER TO A STATIC MEMBER FUNCTION -- WORKS!!
// output = 'Value of the callback: 30'
callback(A::add, 10, 20);
//USING A POINTER TO A NON-STATIC MEMBER FUNCTION -- WORKS!!
int(A::*function1)(int, int) = &A::sub;
// output = 'Non static member: 3'
cout << "Non static member: " << (obj.*function1)(1, 1) << endl;
//PASSING A POINTER TO A NON-STATIC MEMBER FUNCTION -- aargh
// fallita! tutto quello sotto non funziona --> usa i funtori???
// puoi creare una classe wrapper ma non riuscirai mai a chiamare da callback
int(A::*function2)(int, int) = &A::sub;
int(*function3)(int, int) = obj.*function2; //[error] invalid use of non-static member function
callback(function3, 1, 1);
}
There's a way to create my pointer in the way I tried to wrote, like int(*fx)(int, int) = something? I searched a lot but no-one could gave me an answer (well, there was an answer: "NO", but I still think I can do something)
I heard also about functors, may them help me in this case?
Thanks to anyone
PS: sorry for my bad english
EDIT1:
I can use something like this:
template <class T>
void callback2( T* obj, int(T::*fx)(int, int), int a, int b)
{
cout << "Value of the callback: " << (obj->*fx)(a, b) << endl;
}
void callback2( void* nullpointer, int(*fx)(int, int), int a, int b)
{
cout << "Value of the callback: " << fx(a, b) << endl;
}
and in my main:
callback2(NULL, &mul, 5, 3); // generic function, it's like: int mul(int a, int b){return a*b;}
callback2(NULL, &A::add, 5, 3); //static member function
callback2(&obj, &A::sub, 1, 1); //non static member function
I'm not completely sadisfied, because I don't want to pass my 'callback2' the first parameter (the object)...
The question, for people that didn't understand my (bad) explanation, is: can I delete the first parameter in my callback2 function?
the prototype will be
void callback2(int(*fx)(int, int), int a, int b)<br>
and I will call like this:
callback2(&obj.sub, 1, 3);
Functions cannot be referenced this way:
int (*function3)(int, int) = obj.*function2;
You have to pass the address of the function like this:
int (*function3)(int, int) = std::mem_fn(&A::sub, obj);
// ^^^^^^^^^^^^^^^^^^^^^^^^^
The expression function2 decays into a pointer-to-function which allows it to work.
I would do it with std functors, here is a simple example based off of your code:
#include <iostream>
#include <functional>
using namespace std;
class A{
private:
int x;
public:
A(int elem){
x = elem;
}
static int add(int a, int b){
return a + b;
}
int sub(int a, int b) const{
return x - (a + b);
}
};
void callback( std::function<int(const A& ,int,int )> fx, A obj, int a, int b)
{
cout << "Value of the callback: " << fx( obj, a, b) << endl;
}
int main()
{
A obj(5);
std::function<int(const A& ,int,int )> Aprinter= &A::sub;
callback(Aprinter,obj,1,2);
}

Setting a pointer to a non-static member function

I'm trying to setup a function pointer that is set during execution based on a set of user parameters. I would like to have the function pointer point to a non-static member function but I can't find how to do it.
The examples I've seen say this can only be done with static member function only or use global variables in straight C.
A simplified example follows:
class CA
{
public:
CA(void) {};
~CA(void) {};
void setA(double x) {a = x; };
void setB(double x) {b = x; };
double getA(const double x) {return x*a; };
double getB(const double x) {return x*b; };
void print(double f(const double), double x) {
char cTemp[256];
sprintf_s(cTemp, "Value = %f", f(x));
std::cout << cTemp;
};
private:
double a, b;
};
The implementation part is
CA cA;
cA.setA(1.0);
cA.setB(2.0);
double (*p)(const double);
if(true) {
p = &cA.getA; //'&' : illegal operation on bound member function expression
} else {
p = cA.getB; //'CA::getB': function call missing argument list; use '&CA::getB' to create a pointer to member
//'=' : cannot convert from 'double (__thiscall CA::* )(const double)' to 'double (__cdecl *)(const double)'
}
cA.print(p, 3.0);
So how do I get p to point to either 'getA' or 'getB' so that it is still useable by 'print'.
From what I have seen, the suggestions are to use boost or std::bind but I've had no experience with either of these. I'm hoping that I don't need to dive into these and that I'm just missing something.
Compiler MSVC++ 2008
Don't forget that a member function accepts an implicit this parameter: therefore, a member function accepting a double can't be the same thing as a non-member (free) function accepting a double.
// OK for global functions
double (*p)(const double);
// OK for member functions
double (CA:*p)(const double);
Also the way you invoke them is different. First of all, with member functions, you need an object to invoke them on (its address will eventually be bound to the this pointer in the function call). Second, you need to use the .* operator (or the ->* operator if you are performing the call through a pointer):
p = &CA::getA;
CA cA;
(cA.*p)();
Consistently, you will have to change your definition of function print():
#include <iostream>
void print(double (CA::*f)(const double), double x)
{
// Rather use the C++ I/O Library if you can...
std::cout << "Value = " << (this->*f)(x);
};
So finally, this is how you should rewrite your main() function:
int main()
{
CA cA;
cA.setA(1.0);
cA.setB(2.0);
double (CA::*p)(const double);
if (true) // Maybe use some more exciting condition :-)
{
p = &CA::getA;
}
else {
p = &CA::getB;
}
cA.print(p, 3.0);
}
Compilation Issue
This answer focuses on the compilation issue presented in the question. I would not recommend implementing this as a solution.
Pointers to member functions are best dealt with with typedefs and a macro.
Here's the macro for calling a member function:
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
Source: [33.6] How can I avoid syntax errors when calling a member function using a pointer-to-member-function?, C++ FAQ.
This saves you having to remember the ugly (object).*(ptrToMember) syntax any time you wish to call a member function by pointer.
In your class, declare a typedef called CAGetter, this will make variable declaration much simpler:
class CA
{
public:
typedef double (CA::*CAGetter)(const double x);
Then you can declare your print() function quite simply:
void print(CAGetter f, double x)
The body is also simple, clear and concise:
{
std::cout << "value = " << CALL_MEMBER_FN(*this, f)(x) << '\n';
}
Sample usage:
CA a;
a.setA(3.1);
a.setB(4.2);
// Using a variable...
CA::CAGetter p = &CA::getA;
a.print(p, 1);
// without a variable
a.print(&CA::getB, 1);
// Calling the functions from outside the class...
std::cout << "From outside (A): " << CALL_MEMBER_FN(a, p)(10) << std::endl;
std::cout << "From outside (B): " << CALL_MEMBER_FN(a, &CA::getB)(10) << std::endl;
Design Issue
Passing a pointer to a member function into a method of an instance of the same class is a design smell (you wouldn't normally pass a member variable to a method, this is no different). There is not enough information in this question to address the underlying design issue but this problem could probably be solved with separate print() methods, a member variable or with inheritance and polymorphism.
You can either use pointer to method:
class CA
{
public:
typedef double (CA::*getter)( double );
CA(void) {};
~CA(void) {};
void setA(double x) {a = x; };
void setB(double x) {b = x; };
double getA(const double x) {return x*a; };
double getB(const double x) {return x*b; };
void print(getter f, double x) {
char cTemp[256];
sprintf(cTemp, "Value = %f", (this->*f)(x));
std::cout << cTemp;
};
private:
double a, b;
};
int main()
{
CA cA;
cA.setA(1.0);
cA.setB(2.0);
CA::getter p;
if(true) {
p = &CA::getA;
} else {
p = &CA::getB;
cA.print( p, 3.0 );
}
Or use boost::bind
class CA
{
public:
typedef boost::function<double( double )> getter;
CA(void) {};
~CA(void) {};
void setA(double x) {a = x; };
void setB(double x) {b = x; };
double getA(const double x) {return x*a; };
double getB(const double x) {return x*b; };
void print(getter f, double x) {
char cTemp[256];
sprintf(cTemp, "Value = %f", f(x));
std::cout << cTemp;
};
private:
double a, b;
};
int main()
{
CA cA;
cA.setA(1.0);
cA.setB(2.0);
CA::getter p;
if(true) {
p = boost::bind( &CA::getA, &cA, _1 );
} else {
p = boost::bind( &CA::getB, &cA, _1 );
}
cA.print( p, 3.0 );
}