根据上下文对类成员进行不同的访问
假设我有一个类 MainApp 通过接口 FrontEnd 使用动态库的方法 FrontEnd
使用类 Data 的内部实例(包含在类 BackEnd 中)
该类 Data 仅包含一个成员及其访问器,没有公共方法来操作该成员
好吧,现在 MainApp 不了解数据,无法访问它,但它需要间接操作它
我的目标是创建某种引用,保留指向数据的指针,并
- 在 MainApp 中
- 允许访问数据 时有两种行为禁止访问数据什么时候在前端中,
我列出了一些解决方案,例如 PIMPL 惯用语、桥或适配器模式,但问题是我不想像接口一样使用参考,而只是像支架一样
我该如何处理它?
这里有一些代码来说明:
Data.hpp
struct Data {
Data(int i):member(i){}
int getMember();
private :
int member;
};
BackEnd.hpp
#include "Data.hpp"
struct BackEnd {
BackEnd(){}
Data* createData(int i) {
Data* d = new Data(i);
mDatas.push_back(d);
return d;
}
void doSomething(Data* d, int param) {
int r = param+d->getMember();
/*do other things with d*/
}
private:
vector<Data*> mDatas;
};
Reference.hpp
#include //???
struct Reference {
Reference(Data* d):mData(d){}
private:
//no access to data->member
Data* mData;
};
FrontEnd.hpp
#include "Data.hpp"
#include "Reference.hpp"
#include "BackEnd.hpp"
struct FrontEnd {
Reference* createData(int i) {
Data* d = mBackEnd->createData(i);
//conversion Data to Reference
Reference ref = new Reference(d);
return ref;
}
void doSomething(Reference* ref) {
//In the Front-End, I want an access to Ref->mData
Data* d = ref->getData();//Allows access to Ref->mData
int result = mBackEnd->doSomething(d);
}
private:
BackEnd* mBackEnd;
};
MainApp.hpp
//I don't want to reference Data.hpp
#include "Reference.hpp"
#include "FrontEnd.hpp"
struct MainApp {
Reference* createRef(){ mRef = mFrontEnd->createData(8);}
void doSomething(){ mFrontEnd->doSomething(mRef); }
private:
FrontEnd* mFrontEnd;
Reference* mRef;
//I want to keep a reference to Data without using Data directly
//Forbids access to mRef->mData
};
Let's say I have a class MainApp using methods of a dynamic library via an interface FrontEnd
FrontEnd uses internally instances of a class Data (contained in a class BackEnd)
This class Data only contains a member and its accessor, no public method to manipulate the member
Ok now MainApp has no knowledge of Data and can't access it but it needs indirectly to manipulate it
My goal is to create some kind of a reference keeping a pointer to Data with 2 behaviours
- forbidding access to Data when in MainApp
- Allowing access to Data when in FrontEnd
I listed some solutions like PIMPL idiom, Bridge or Adaptor pattern but the problem is I don't want to use the Reference like an interface but just like an holder
How can I handle it?
Here some code to illustrate:
Data.hpp
struct Data {
Data(int i):member(i){}
int getMember();
private :
int member;
};
BackEnd.hpp
#include "Data.hpp"
struct BackEnd {
BackEnd(){}
Data* createData(int i) {
Data* d = new Data(i);
mDatas.push_back(d);
return d;
}
void doSomething(Data* d, int param) {
int r = param+d->getMember();
/*do other things with d*/
}
private:
vector<Data*> mDatas;
};
Reference.hpp
#include //???
struct Reference {
Reference(Data* d):mData(d){}
private:
//no access to data->member
Data* mData;
};
FrontEnd.hpp
#include "Data.hpp"
#include "Reference.hpp"
#include "BackEnd.hpp"
struct FrontEnd {
Reference* createData(int i) {
Data* d = mBackEnd->createData(i);
//conversion Data to Reference
Reference ref = new Reference(d);
return ref;
}
void doSomething(Reference* ref) {
//In the Front-End, I want an access to Ref->mData
Data* d = ref->getData();//Allows access to Ref->mData
int result = mBackEnd->doSomething(d);
}
private:
BackEnd* mBackEnd;
};
MainApp.hpp
//I don't want to reference Data.hpp
#include "Reference.hpp"
#include "FrontEnd.hpp"
struct MainApp {
Reference* createRef(){ mRef = mFrontEnd->createData(8);}
void doSomething(){ mFrontEnd->doSomething(mRef); }
private:
FrontEnd* mFrontEnd;
Reference* mRef;
//I want to keep a reference to Data without using Data directly
//Forbids access to mRef->mData
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
考虑使用友谊 - 即使
FrontEnd
成为Reference
的friend
,这样您就可以在protected
成员中< code>Reference 将允许您获取Data*
。在Reference.h
中,包含FrontEnd.h
(以允许友谊),在FrontEnd.h
中,使用Reference
作为前向声明(即不包含标头)。仅在FrontEnd
的实现文件中包含标头。您还必须将所有定义(在FrontEnd.h
中)移至实现文件。现在
MyApp
可以愉快地保存Reference
,但是Data*
只能通过FrontEnd
获取。Consider using friendship - i.e. make
FrontEnd
afriend
ofReference
, this way you can have aprotected
member inReference
which will allow you to get theData*
. InReference.h
, includeFrontEnd.h
(to allow friendship), inFrontEnd.h
, useReference
as a forward declaration (i.e. don't include the header). Only include the header in the implementation file forFrontEnd
. You'll have to move all the definitions (inFrontEnd.h
to the implementation file as well.Now
MyApp
can happily hold aReference
butData*
can only be got at byFrontEnd
.如果您想允许外部类访问另一个类的内部,您可以将其设置为
朋友
。这显然是一种权衡。以不同的方式思考这两个结构是可以的,但是如果它们访问彼此的内部结构,那么它们就没有太多的关注点分离。谨慎使用。
当您执行此操作时,最好通过方法调用访问内部,而不是直接操作它们。看起来您似乎正在增加复杂性,而且在某种程度上确实如此。不过,它使您的访问意图变得清晰。
例如,您不希望计数检查散落在整个
Foo
中。If you want to allow external classes access to internals of another you can set it as a
friend
.This is a trade off obviously. It is alright to think about the two structs differently, but if they access each others internals they don't have much separation of concern. Use sparingly.
When you do this it is good practice to access the internals via method calls as opposed to manipulating them directly. It may seem like you are adding complexity and you are to some extent. It makes your access intentions clear, though.
You wouldn't want that count check littered throughout
Foo
, for example.