从C++中不同类的成员函数访问数据

Data access from a member function of different classes in C++

本文关键字:成员 函数 访问 数据 同类 C++      更新时间:2023-10-16

我很困惑如何从不同的类实现数据成员访问。我在三个不同的头文件中有三个类。

A.h
#include "B.h"
#include "C.h"
class A{
    B *b;
    friend void dataaccess_b_from_class_A(int a);
}
B.h
class B{
}
C.h
class C{
   void dataaccess_b_from_class_A(int a);
}
void C::dataaccess_b_from_class_A(int a)
{
   b = new B(); //I got error as symbol b could not be resolved.
}

我喜欢来自class Cdataaccess_b_from_class_A()方法访问来自Class A的数据B *b。我把friend函数放在了class A中,但我得到了error as symbol b could not be resolved。我该如何实现它?

第1版:根据讨论"gmas80",我做的是

class B; // forward declaration
class A{
public:
    A(){};
private:
    static B* b; // since in the dataaccess_to_class_A you are using new
    friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
    B(){ cout << "B" << endl; };
   // add content
};
class C{
public: // you need this keyword if you want to call this function from outside
   void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
   A::b = new B(); //Error as undefined reference to class A::b
   cout << "C" << endl; // test if called
}

如果我不包括static,我得到b could not be resolved。如果我包括静态,我得到undefined reference。感谢

在这么小的一段代码中包含了这么多错误!你为什么不简单一点开始呢?这里有一个修改后的单文件版本的代码编译:

#include <iostream>
using namespace std;
class B; // forward declaration
class A{
public:
    A(){};
private:
    B* b; // since in the dataaccess_to_class_A you are using new
    void dataaccess_from_class_C(){ cout << "A" << endl; }; // test if called
    friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
    B(){ cout << "B" << endl; };
   // add content
};
class C{
public: // you need this keyword if you want to call this function from outside
   void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
   a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
   a.dataaccess_from_class_C();
   cout << "C" << endl; // test if called
}
// it is better if you post runnable code
int main() {
    C c;
    A a;
    c.dataaccess_to_class_A(a);
}

编辑后1

现在,您可以开始在头文件中移动类,但需要添加守护者以避免多重定义。。

a.h

#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B; // forward declaration
class A
{
public:
    A()
    {};
private:
    B* b; // since in the dataaccess_to_class_A you are using new
    void dataaccess_from_class_C()
    {
        cout << "A" << endl;
    }; // test if called
    friend class C; // this make b and dataaccess_from_class_C accessible
};
class B
{
public:
    B()
    {
        cout << "B" << endl;
    };
    // add content
};
class C
{
public: // you need this keyword if you want to call this function from outside
    void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
    a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
    a.dataaccess_from_class_C();
    cout << "C" << endl; // test if called
}
#endif

main.cpp

#include "a.h"
// it is better if you post runnable code
int main()
{
    C c;
    A a;
    c.dataaccess_to_class_A( a );
}

这对你来说有意义吗?我只是简单地移动了包含的另一个文件中的类声明。。

EDIT2

现在我们将类定义拆分为三个不同的头。。

a.h

#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B;
class A
{
public:
    A(): b(NULL){}; // initialize to NULL the b pointer
    ~A(); // new entry: destructor to eventually delete b (only member function declaration)
private:
    B* b; // since in the dataaccess_to_class_A you are using new
    void dataaccess_from_class_C()
    {
        cout << "A" << endl; // test if called
    }; 
    friend class C; // this make b and dataaccess_from_class_C accessible
};
#endif

a.cp//新条目!它避免了循环依赖。。这里定义了析构函数

#include "a.h"
#include "b.h"
A::~A() // destructor that eventually clean memory for b
{
    if( b ) delete b;
}

b.h

#ifndef H_GUARDIAN_B
#define H_GUARDIAN_B
#include "a.h"
class B
{
public:
    B()
    {
        cout << "B" << endl;
    };
    // add content
};
#endif

c.h

#ifndef H_GUARDIAN_C
#define H_GUARDIAN_C
#include "b.h"
class C
{
public: // you need this keyword if you want to call this function from outside
    void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
    a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
    a.dataaccess_from_class_C();
    cout << "C" << endl; // test if called
}
#endif

main.cpp

#include "c.h"
// it is better if you post runnable code
int main()
{
    C c;
    A a;
    c.dataaccess_to_class_A( a );
}

添加

include "B.h"

如果C.h并定义b 的类型

B b( new B() );

另外,在freind声明中指定完全限定的方法:

friend void C::dataaccess_b_from_class_A(int a);

将C.h包括在A.h中,并且不要忘记在每个报头中包括保护

还有一点。为什么在标题中定义C::dataaccess_b_from_class_A?我建议把它单独归档。比如说"C.cpp"。