I am a beginner learning C++. While studying the topic of friends, I would like to try establishing a friend relationship between the class A in a.h
and the class B in b.h
, specifically for the get_value() member function.
this is my code:
// a.h
#ifndef A_H
#define A_H
#include "b.h"
class A;
class A {
friend void B::get_value(A&);
private:
double m;
int n;
public:
A(double m = 100, int n = 200) : m(m), n(n) {}
};
#endif
// b.h
#ifndef B_H
#define B_H
class A;
class B {
public:
void get_value(A&);
};
#include "a.h"
#include <iostream>
void B::get_value(A& a) {
std::cout << a.m << a.n << std::endl;
return;
}
#endif
// test.cpp
#include "a.h"
#include "b.h"
int main() {
A a;
B b;
b.get_value(a);
return 0;
}
Writing it like this would result in an error, and the error message would be as follows:
E:/project/cpp_project/cpp_study/1. complex/b.h: In member function 'void B::get_value(A&)':
E:/project/cpp_project/cpp_study/1. complex/b.h:18:18: error: invalid use of incomplete type 'class A'
18 | std::cout << a.m << a.n << std::endl;
I tried alternative approache:
define B::get_value(A&)
in a.h
:
// a.h
#ifndef A_H
#define A_H
#include "b.h"
class A;
class A {
friend void B::get_value(A&);
private:
double m;
int n;
public:
A(double m = 100, int n = 200) : m(m), n(n) {}
};
#include <iostream>
void B::get_value(A& a) {
std::cout << a.m << a.n << std::endl; // 访问A类的私有成员m和n
return;
}
#endif
// b.h
#ifndef B_H
#define B_H
class A; // 前置声明A类
class B {
public:
void get_value(A&);
};
#endif
It doesn't work but the error message has changed:
E:/project/cpp_project/cpp_study/1. complex/a.h:21: multiple definition of `B::get_value(A&)'; CMakeFiles/cpp_study.dir/1._complex/test.cpp.obj:E:/project/cpp_project/cpp_study/1. complex/a.h:21: first defined here
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Finally, I reached out to New Bing for help, and I received the answer. It move the definition of B::get_value()
into b.cpp:
// a.h
#ifndef A_H
#define A_H
#include "b.h"
class A;
class A {
friend void B::get_value(A&);
private:
double m;
int n;
public:
A(double m = 100, int n = 200) : m(m), n(n) {}
};
#endif
// b.h
#ifndef B_H
#define B_H
class A; // 前置声明A类
class B {
public:
void get_value(A&);
};
#endif
// b.cpp
#include "b.h" // 包含B类的定义
#include "a.h"
#include <iostream>
void B::get_value(A& a) {
std::cout << a.m << a.n << std::endl; // 访问A类的私有成员m和n
return;
}
It works but I don't understand. I hope someone can tell me why my code is error-prone and why bing's code is right.