gpt4 book ai didi

c++ - 如何在不弄乱图书馆内部访问的情况下正确设计图书馆的外部访问?

转载 作者:行者123 更新时间:2023-11-28 01:59:13 25 4
gpt4 key购买 nike

我正在尝试设计一个库,只向调用者开放几个接口(interface),而不会弄乱它自己的内部访问控制。正确的做法是什么?

例如,这里是库:

namespace ControlledLib {
class ThinkTrack1 {
friend class DeepThought;
friend class ThinkTrack2;
private:
int ResultA() { return 6; }
int ResultB() { return 5; }
};

class ThinkTrack2 {
friend class DeepThought;
private:
int ResultC() { ThinkTrack1 tt1; return tt1.ResultB() + 2; }
};

class DeepThought {
friend int DeepThoughtAnswers();
private:
int Answers() {
ThinkTrack1 tt1;
ThinkTrack2 tt2;
return tt1.ResultA() * tt2.ResultC();
}
int CreateWorld() {
return 7;
}
};

int DeepThoughtAnswers() { DeepThought dt; return dt.Answers(); }
}

, 可以调用

#include "ControlledLib.h"

int i = ControlledLib::DeepThoughtAnswers();

实际答案由 class DeepThought 的函数 Answers() 给出,但是,只有一个 Answers() 可以访问外部调用者,我必须将 class DeepThought 的函数设为 private,并发明一个全局函数 DeepThoughtAnswers() 作为入口点,它调用class DeepThought 得到答案,然后 class DeepThought 必须将 DeepThoughtAnswers() 定义为 friend 函数。

一切才刚刚开始。由于 class DeepThought 实际上调用了 class ThinkTrack1class ThinkTrack2,而 class ThinkTrack2 调用了 class ThinkTrack1 等等... 为了让外部调用者无法访问所有这些,所有这些函数都设置为private,我必须定义很多friendship。最重要的是,所有这些都扰乱了内部访问控制!

什么是更好的方法?

最佳答案

在设计界面时,您可以选择一些选项。第一种是只定义一个导出一组函数的 C 接口(interface)。这些函数在内部调用您的类,这些类通过这一层隐藏。

<ControlledLib.h>
extern "C" int DeepThoughAnswers();
</ControlledLib.h>

在源文件中你有这个函数的实现:

<ControlledLib.cpp>
#include "DeepThought.h"
#include "ThinkTrack1.h"
#include "ThinkTrack2.h"

int DeepThoughAnswers()
{
DeepThought dt;
return dt.Answers();
}
</ControlledLib.cpp>

您在此源中包含的文件然后使用没有 friend 的可见性,并且您只运送生成的库和 ControlledLib.h 文件。

另一种方法是使用 C++ 接口(interface)来隐藏实现细节。界面来了:

<ControlledLib.h>
class ControlledLib
{
public:
virtual int DeepThoughAnswers() = 0;
};
</ControlledLib.h>

然后你有这个接口(interface)的实现,它可能看起来像这样:

<MyControlledLib.h>
class MyControlledLib : public ControlledLib
{
public:
virtual int DeepThoughAnswers();
void someOtherFunction(); //<-- not visible to the 'outside'
};
</MyControlledLib.h>

此外,您还添加了一个允许客户端实例化您的库的工厂。

<ControlledLib.h>
#include "ControlledLib.h"

class MyControlledLibFactory
{
public:
static MyControlledLib* create();
};
</MyControlledLib.h>

对于客户,您只需提供工厂和接口(interface),其他一切都是隐藏的。到目前为止,您的接口(interface)仅使用原始类型,这意味着您不必导出任何其他类型。如果你想在你的界面中使用类,你也需要导出它们以供使用。

<ControlledLib.h>
class ControlledLib
{
public:
virtual int DeepThoughAnswers() = 0;
virtual ComplexAnswer* DeepThoughAnswersAreComplex() = 0; //<-- ComplexAnswer header needs to be supplied too.
};
</ControlledLib.h>

关于c++ - 如何在不弄乱图书馆内部访问的情况下正确设计图书馆的外部访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40143876/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com