C ++朋友类数据访问

时间:2011-03-20 21:07:13

标签: c++

C ++ newbie here。

我是一个科学家,正在写一个cfd(ish)代码。我为所有求解函数创建了一个类,并且为网格上的操作创建了一个类。网格类希望能够看到解决类中存储的一些变量,因为将它们全部传递给网格类似乎需要付出一些努力。

所以在我的研究中,我遇到了朋友课,但似乎无法让它发挥作用。请参阅下面的完全缩减示例。 A类是求解器,它创建了一个网格类B.即使我写了好友类B,我仍然得到以下编译错误(g ++):

在成员函数'void B :: testB()'中:

错误:未在此范围内声明'a1'

以下是代码:

#include <iostream>
using namespace std;
class B {
private:
    int b1;

public:
    void testB(){
        cout<<a1<<endl;
    };  


};

class A {
friend class B;

private:
    int a1;

public:
    void testA(){
        a1=2;
        B b;
        b.testB();
        };
};


int main(){
    A a;
    a.testA();
}

7 个答案:

答案 0 :(得分:4)

a1仅作为A类的实例的一部分存在。换句话说,您需要一个A对象才能访问a1。

编辑: 但事实证明,这不是你提供的来源中唯一的问题。

这有效:

#include <iostream>
using namespace std;

class B;

class A {
  friend class B;
  private:
    int a1;
  public:
    void testA();
};

class B {
private:
    int b1;

public:
    void testB(A *a){
        cout << (a->a1) << endl;
    }
};

void A::testA() {
    this->a1 = 2;
    B b;
    b.testB(this);
}


int main(){
    A a;
    a.testA();
}

答案 1 :(得分:3)

这就是你应该如何编码:(请阅读评论!)

#include <iostream>
using namespace std;

class A 
{
    friend class B; //this means, B can access private members of A!
private:
    int a1; //private member data

public:
    A (int a) : a1(a) {}
private:
    void testA() //private member function
    {
       cout << a1 << endl;
    }
};

class B {
    int b1;
public:
    void testB()
    {
        A a(100);
        cout<<a.a1<<endl; //B is accessing A's private member data!
        a.testA();        //B is accessing A's private member function!
    }
};    
int main(){
    B b;
    b.testB();
}

在线演示:http://ideone.com/LDEOO

阅读以下教程:

答案 2 :(得分:2)

你很困惑。 friend - 声明对于授予类私有或受保护成员的类或函数访问权限非常有用。它们不一定是你想要的。您可能只希望B引用A,就像其他人建议的那样:

class A;

class B {
public:
    B(A & a) : a(a) {}
private:
    A & a;
};

要让B能够访问A的私人或受保护成员,您有两种选择:

  1. 使用公共访问者:

    class A {
    public:
        // You can also make this function returns a const reference
        int getItem() const { return item; }
    private:
        int item;
    };
    

    这样你就不需要朋友声明了。

  2. 使用friend声明。

  3. 您可能需要阅读what the C++FAQ-Lite has to say about this

答案 3 :(得分:0)

你必须提供一个对象a1。像这样:

#include <iostream>
using namespace std;

class A {
friend class B;

private:
    int a1;

public:
    void testA();
};

class B {
private:
    int b1;

public:
    void testB(A &a){
        cout<<a.a1<<endl;
    }  
};

void A::testA(){
    a1=2;
    B b;
    b.testB(*this);
}


int main(){
    A a;
    a.testA();
}

答案 4 :(得分:0)

您需要一个类B的实例来访问其成员。试试

void testB(B *b){
    cout << b->a1 << endl;
};

答案 5 :(得分:0)

A.H

#ifndef A_H
#define A_H

class B;

class A
{
friend class B;

private:
    int a1;

public:
    void testA();
};
#endif

B.h

#ifndef B_H
#define B_H

#include <iostream>

#include "A.h"

class B
{
private:
    int b1;

public:
    void testB(A &a)
    {
        std::cout << a.a1 << std::endl;
    }
};
#endif

A.cpp

#include "A.h"
#include "B.h"

void A::testA()
{
    a1 = 2;
    B b;
    b.testB(*this);
}

的main.cpp

#include "A.h"
#include "B.h"

int main()
{
    A a;
    a.testA();
}

g++ main.cpp A.cpp -o test

./test

打印:

2

建议:

  • 尝试将您的程序划分为多个 文件,就像我做的那样。标题和定义应该分开。它简化了 调试,阅读,使用等。
  • 切勿在标题内使用using 文件。

答案 6 :(得分:0)

既然你说你正在研究CFD,我认为这个问题是错误的。您应该使用像Eigen / Lapack / Vtk库这样的东西,并遵循那里的风格。也许您可以说为什么需要朋友功能来与您的网格进行交互?

我的类似故事:在我用c ++做得很好之前,我很难理解大型库,而且我在你的问题中写了一些东西。现在我重用那里的东西,只为新功能编写低级数学代码。我怀疑你处于类似情况。