【发布时间】:2021-08-25 04:41:14
【问题描述】:
我正在尝试使用朋友功能。该函数应该是我拥有的所有类的朋友。但我收到多个错误,其中一些是 incomplete type。以下是我拥有的文件:
main.cpp
#include <iostream>
#include "my_ClassA.h"
#include "my_ClassB.h"
#include "my_ClassC.h"
#include "my_ClassD.h"
int main()
{
std::cout<<"Hello World";
my_namespace::my_ClassA object1;//this will do some computation and set everything up for object1
my_namespace::my_ClassB object2(object1);//this object2 will use object1 to further do other computation
my_namespace::my_ClassC object3(object2);
my_namespace::my_classD object4(object4);
//runComputation(object1, object2, object3, object4);
return 0;
}
my_ClassA.h
#pragma once
#include<string>
#include <vector>
//these three includes are for friend function BUT result in error incomplete type
#include "my_ClassB.h"
#include "my_ClassC.h"
#include "my_ClassD.h"
/////////////////////////////////////////////
namespace my_namespace{
class my_ClassA{
friend void runComputation(my_ClassA&,my_ClassB&,my_ClassC&,my_ClassD&);
private:
std::string name;
std::vector<std::string> vec;
public:
std::vector<std::string> get_vec();
};
void runComputation(my_ClassA&,my_ClassB&,my_ClassC&,my_ClassD&);
}
my_ClassA.cpp
#include "my_ClassA.h"
std::vector<std::string> my_namespace::my_ClassA::get_vec(){
return vec;
}
my_ClassB.h
#pragma once
#include<string>
#include <vector>
#include "my_ClassA.h"
#include "my_ClassC.h"
#include "my_ClassD.h"
namespace my_namespace{
class my_ClassB{
friend void runComputation(my_ClassA&,my_ClassB&,my_ClassC&,my_ClassD&);
private:
std::string name;
std::vector<std::string> vec;
public:
std::vector<std::string> get_vec();
my_ClassB(my_ClassA);
my_ClassB(){
;
}
};
}
my_ClassB.cpp
#include "my_ClassB.h"
std::vector<std::string> my_namespace::my_ClassB::get_vec(){
return vec;
}
my_namespace::my_ClassB::my_ClassB(my_ClassA temp_objA){
;
}
my_ClassC.h
#pragma once
#include<string>
#include <vector>
#include "my_ClassB.h"
#include "my_ClassA.h"
#include "my_ClassD.h"
namespace my_namespace{
class my_ClassC{
friend void runComputation(my_ClassA&,my_ClassB&,my_ClassC&,my_ClassD&);
private:
std::string name;
std::vector<std::string> vec;
my_ClassB objB;
public:
my_ClassC(my_ClassB);
std::vector<std::string> get_vec();
};
}
my_ClassC.cpp
#include "my_ClassC.h"
#include "my_ClassB.h"
std::vector<std::string> my_namespace::my_ClassC::get_vec(){
return vec;
}
my_namespace::my_ClassC::my_ClassC(my_ClassB temp_objB){
;
}
my_ClassD.h
#pragma once
#include<string>
#include <vector>
#include "my_ClassA.h"
#include "my_ClassB.h"
#include "my_ClassC.h"
namespace my_namespace{
class my_ClassD{
friend void runComputation(my_ClassA&,my_ClassB&,my_ClassC&,my_ClassD&);
private:
std::string name;
std::vector<std::string> vec;
my_ClassA objA;
public:
std::vector<std::string> get_vec();
};
}
my_ClassD.cpp
#include "my_ClassD.h"
std::vector<std::string> my_namespace::my_ClassD::get_vec(){
return vec;
}
我尝试使用 main.cpp 中每个类的 getter。但是我的一些类有大尺寸的向量、集合等。所以我不想一次又一次地复制它们。因此,我想直接在一个名为 runComputation 的函数中访问类的数据成员。并且该函数会将创建的对象作为引用,这样就不会在 main.cpp 中发生复制。
我所拥有的是:首先我创建不同的对象,这些对象可以将先前创建的对象作为 main.cpp 中的输入。成功创建所有对象后,我想对这些对象运行一些计算。现在的问题是我可以使用在 main.cpp 文件中创建的对象的 getter 和 setter。但是这些对象内部有大向量和其他对象,因此每次我在使用 getter 的 for 循环中使用它们时都会复制它们。为了避免这种情况,我想创建一个可以将这些对象作为引用并避免复制的友元函数。我该如何解决这个问题?有没有更好的方法来实现这一点?
PS:我知道 ADL。当我写一个像friend void runComputation(someobject&);这样的朋友声明时会使用ADL,然后在类之后使这个朋友函数可见void runComputation(someobject&);
【问题讨论】:
-
没有足够的时间给出正确答案,但问题可能是相互包含(例如 A.h 包括 B.h,反之亦然)。只需手动查看包含指令的结果。您可以通过在 B.h 中仅使用一个类(例如 A)来解决此问题,对于该类,时尚
class A;的“前向声明”就足够了,没有标题。如果 B.h 中没有代码访问 A 的成员或创建对象但仅使用指针或引用,例如作为函数参数或成员(因为可以在不知道类的实现的情况下生成指针和引用的代码)。 -
I tried using the getters of each of the classes in the main.cpp. But some my classes have large size vectors,sets etc etc. So i do not want to copy them again and again.只使用 getter,返回 const 引用或非 const 引用 -
@George 我在我的第二行中陈述了一个错误。检查。现在我已经强调了它。在它是普通文本之前。
-
友谊是完全无关的——你的类之间存在循环依赖,你需要打破这种依赖。阅读您最喜欢的 C++ 书籍中的前向声明(和引用)。
-
@molbdnilo 是的,我认为这主要是因为循环依赖。我已经知道前向声明和引用。顺便说一句,我不确定我们是否可以使用返回对数据成员的引用的 getter。例如,通常当我使用普通函数时,返回对局部变量的引用是 UB。那么从 getter 返回对数据成员的引用是可以的还是一种不好的做法?
标签: c++ c++11 c++14 friend friend-function