注册 登录
编程论坛 C++教室

友元 有点迷惘?

发布于 2010-10-30 19:39, 472 次点击
  这个程序有两个错误,不过我都不知道怎样改,请各位高手帮帮忙。
#include<iostream>
using namespace std;
class CLine;
class CPoint   //一条直线的一个点
{
    friend void CLine::GetInterPoint(CLine &line);     //友元函数   这语句编译不过,我也不知道为什么,前面我已先定义了 class CLine
      
public:
    CPoint(int x1=0,int y1=0)
    {
      x=x1;
      y=y1;
    }
public:
    int x,y;
   
};


class CLine
{

public:
    void GetInterPoint(CLine &line);
    void Print()                             //输出直线方程
    {
       a=(float)(pt2.y-pt1.y)/(pt2.x-pt1.x);
       b=pt1.y-a*pt1.x;
       cout<<"y="<<a<<"x+"<<b<<endl;
    }
    CLine(CPoint&a,CPoint&b)
    {
      pt1.x=a.x,pt1.y=a.y;
      pt2.x=b.x,pt2.y=b.y;   
    }


private:
    CPoint pt1,pt2;
    float a,b,m,n;

};

void CLine::GetInterPoint(CLine &line)             //求两直线的交点(x,y)
{
  m=(line.b-(*this).b)/((*this).a-line.a);
    cout<<"x="<<m<<endl;
  n=(line.a)*(line.b-(*this).b)/((*this).a-line.a)+line.b;
  cout<<"y="<<n<<endl;

}

int main()
{
  CPoint l1(2,3);
  CPoint l2(5,6);
  CPoint l3(1,1);
  CPoint l4(4,7);
  CLine line1(l1,l2);
  line1.Print();
  CLine line2(l3,l4);
  line2.Print();
  line1.GetInterPoint(CLine &line2);   //说是非法调用
  return 0;
 
}

编译器编译出现的错误:
f:\vc的程序\11-11\11-11.cpp(6) : error C2027: use of undefined type 'CLine'
        f:\vc的程序\11-11\11-11.cpp(3) : see declaration of 'CLine'
f:\vc的程序\11-11\11-11.cpp(63) : error C2275: 'CLine' : illegal use of this type as an expression
        f:\vc的程序\11-11\11-11.cpp(21) : see declaration of 'CLine'
执行 cl.exe 时出错.

11-11.obj - 1 error(s), 0 warning(s)
6 回复
#2
m21wo2010-10-30 20:34
程序代码:
#include<iostream>
using namespace std;
class CLine;
class CPoint   //一条直线的一个点
{
    friend void GetInterPoint(CLine &line);     //友元函数   这语句编译不过,我也不知道为什么,前面我已先定义了 class CLine
      
public:
    CPoint(int x1=0,int y1=0)
    {
      x=x1;
      y=y1;
    }
public:
    int x,y;
  
};


class CLine
{

public:
    void GetInterPoint(CLine &line);
    void Print()                             //输出直线方程
    {
       a=(float)(pt2.y-pt1.y)/(pt2.x-pt1.x);
       b=pt1.y-a*pt1.x;
       cout<<"y="<<a<<"x+"<<b<<endl;
    }
    CLine(CPoint&a,CPoint&b)
    {
      pt1.x=a.x,pt1.y=a.y;
      pt2.x=b.x,pt2.y=b.y;   
    }


private:
    CPoint pt1,pt2;
    float a,b,m,n;

};

void CLine::GetInterPoint(CLine &line)             //求两直线的交点(x,y)
{
  m=(line.b-(*this).b)/((*this).a-line.a);
    cout<<"x="<<m<<endl;
  n=(line.a)*(line.b-(*this).b)/((*this).a-line.a)+line.b;
  cout<<"y="<<n<<endl;

}

int main()
{
  CPoint l1(2,3);
  CPoint l2(5,6);
  CPoint l3(1,1);
  CPoint l4(4,7);
  CLine line1(l1,l2);
  line1.Print();
  CLine line2(l3,l4);
  line2.Print();
  line1.GetInterPoint(line2);   //说是非法调用
  return 0;

}
#3
2010-10-31 21:26
我的程序中  friend void CLine::GetInterPoint(CLine &line);这句定义错误,你知道是为什么吗?
我看到书中也是这样写, 而要改为friend void GetInterPoint(CLine &line);
这两句有什么不同的含义,书中有什么错的吗?还是语境不同定义也不同,我是参照下面的例子写的。
#include<iostream>
using namespace std;
class CRect;
class CPoint
{
public:
    void Inflate(CRect &rc,int nOffset);
    CPoint(int x=0,int y=0)
    {
      xPos=x; yPos=y;
    }
    void Print()
    {
       cout<<"Point("<<xPos<<","<<yPos<<")"<<endl;
   
    }
private:
    int xPos,yPos;

};
class CRect
{
    friend void CPoint::Inflate(CRect &rc,int nOffset); //就是这一句,参考了就出现问题,你说是什么原因。
public:
    CRect(int x1=0,int y1=0,int x2=0,int y2=0)
    {
      xLeft=x1;  xRight=x2;
      yTop=y1;   yBottom=y2;   
    }

    void Print()
    {
       cout<<"Rect("<<xLeft<<","<<yTop<<","<<xRight<<","<<yBottom<<")"<<endl;
    }
private:
    int xLeft,yTop,xRight,yBottom;
};
void CPoint::Inflate(CRect &rc,int nOffset)
{
    xPos+=nOffset;  yPos+=nOffset;
    rc.xLeft+=nOffset;  rc.xRight+=nOffset;
    rc.yTop+=nOffset;   rc.yBottom+=nOffset;

}

int main()
{
  CPoint pt(10,20);
  CRect rc(0,0,100,80);
  pt.Print();
  rc.Print();
  pt.Inflate(rc,3);
  pt.Print();  rc.Print();
  return 0;

}
#4
m21wo2010-10-31 21:59
作用域运算" ::" ,一般用作指明在外的类的成员函数 所属的类!!
#5
2010-10-31 22:10
那我的第二个例子中的那行又怎样解释呢,我实在是弄不明白,至于指明类外的成员函数,这还好理解,
但在第二个例子中不是在类外的。
#6
weiqiang2010-11-03 20:34
学习来的
#7
pangding2010-11-03 21:23
你第二个例子里,Cpoint 先定义的,里面的细节全知道。后面就可以用。
但你自己的例子里,只声明了 CLine 是个类,编译器并不知道里面有什么函数。你引用的东西的类型,是编译器暂未知的,所以提示是未定义。
二楼的例子里只是声明了一个普通函数就可以,虽然那个函数的参数用了个未知类型,但向前声明过了(就是最开始的那个 class CLine),所以是合法的。是因为成员函数和普通函数有本质区别,所以語法也有区别。

C++ 語法太混乱,所以要避免复杂。有的时候即使代码编译器认识,人也不认识,或者很难读。如果可以不用,就避免掉。
1