2

Problems with direct declaration - Friend functions and line / point classes

 2 years ago
source link: https://www.codesd.com/item/problems-with-direct-declaration-friend-functions-and-line-point-classes.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Problems with direct declaration - Friend functions and line / point classes

advertisements

I have a demo program for understanding of friend function. I am stuck up with errors related to forward declaration stuff, I guess.

I have a point class which has x & y co-ordinates. The line class has two objects of point class. Now I have a function in line class which will calculate the slope of the line.

This is my program:

#include <iostream>
using namespace std;

class point
{
    int x,y;
public:
    point(int,int);
    point();
    friend float line::slope();
};

point::point(int a, int b)
{
    x=a;
    y=b;
}

point::point()
{
}

class line
{
    point p1,p2;
public:
    line(point,point);
    float slope();
};

line::line(point p1, point p2)
{
    this->p1=p1;
    this->p2=p2;
}

float line::slope()
{
    float s;
    s=((float)p2.y-p1.y)/(p2.x-p1.x);
    return s;
}

int main()
{
    float sl;
    point obj(5,10);
    point obj1(4,8);
    line obj3(obj,obj1);
    sl=obj3.slope();
    cout<<"\n slope:"<<sl;
    return 0;
}

It is giving me compiler errors with respect to forward declarations due to the following:

  1. When I try to define my line class first, it does not know about the point class. Even if I forward declare the point class, that wont suffice coz to create objects of the point class, the compiler should know the size of the point class and hence the whole class itself. Understood it through explanation in this answer: https://stackoverflow.com/a/5543788

  2. If I define the point class first, it needs to know the friend function slope and hence the class line. So I tried to provide the forward declaration for the line class and the slope function like this before defining the point class:

class line;

float line::slope();

class point
{
    int x,y;
public:
    point(int,int);
    point();
    friend float line::slope();
};

Now this gives me the following errors:

friend1.cpp:5: error: invalid use of incomplete type ‘struct line’
friend1.cpp:4: error: forward declaration of ‘struct line’
friend1.cpp:13: error: invalid use of incomplete type ‘struct line’
friend1.cpp:4: error: forward declaration of ‘struct line’
friend1.cpp: In member function ‘float line::slope()’:
friend1.cpp:9: error: ‘int point::y’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::y’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::x’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::x’ is private
friend1.cpp:43: error: within this context

.3. Next I tried to separate out the point class in point.h and point.cpp and line class in line.h and line.cpp. But still here there is a dependency on each other.

Though this should be possible theoretically, I cannot figure it out how to get it working.

Looking out for answers.

Thanks,

PS: This program is an effort to demonstrate the usage of friend functions alone. Where friend functions are of two types, this is an effort to deal with the second of this kind:

  1. Friend functions which are independent.
  2. Friend functions which are members of another class.

So, usage of friend classes are ruled out in this case.


Add line as a friend, not just a method:

 friend class line;

Other remarks:

  • separate declarations from the implementations in header and implementation files.
  • prefer full qualification over using directives (i.e. remove using namespace std; and use std::cout instead.
  • prefer pass-by-reference for complex types - change line(point,point); to line(const point&, const point&);

EDIT For educational purposes - You can't declare that specific function as friend as the code is now because there's no full definition of the line class. Ergo, the following is the only approach:

class point;
class line
{
    point *p1,*p2;
public:
    line(point,point);
    float slope();
};

class point
{
    int x,y;
public:
    point(int,int);
    point();
    friend float line::slope();
};

You forward-declare point and change the point members in line to point* (because point isn't a complete type yet). In point you now have the full definition of the line class, so you can declare the method as friend.

EDIT 2: For this particular scenario, it's not possible using point objects inside line because you'd need the full type. But line would also have to be fully defined in order to declare its member as friend.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK