gpt4 book ai didi

C++ - 允许通过基类(接口(interface))访问,禁止通过派生类(具体实现)访问?

转载 作者:搜寻专家 更新时间:2023-10-30 23:59:38 28 4
gpt4 key购买 nike

假设我有纯抽象类 IHandler 和派生自它的类:

class IHandler
{
public:
virtual int process_input(char input) = 0;
};

class MyEngine : protected IHandler
{
public:
virtual int process_input(char input) { /* implementation */ }
};

我想在我的 MyEngine 中继承那个类,这样我就可以将 MyEngine* 传递给任何需要 IHandler* 的人,并让他们能够使用 process_input 。但是,我不想允许通过 MyEngine* 进行访问,因为我不想公开实现细节。

MyEngine* ptr = new MyEngine();
ptr->process_input('a'); //NOT POSSIBLE
static_cast<IHandler*>(ptr)->process_input('a'); //OK
IHandler* ptr2 = ptr; //OK
ptr2->process_input('a'); //OK

这可以通过 protected 继承和隐式转换来完成吗?我只设法得到:

conversion from 'MyEngine *' to 'IHandler *' exists, but is inaccessible

由于我是C#出身,所以这基本上是C#中的显式接口(interface)实现。这是 C++ 中的有效方法吗?

附加:

为了更好地了解我为什么要这样做,请考虑以下内容:

TcpConnection 通过 TCP 实现通信,并且在其构造函数中需要指向接口(interface) ITcpEventHandler 的指针。当 TcpConnection 在套接字上获取一些数据时,它使用 ITcpEventHandler::incomingData 将该数据传递给它的 ITcpEventHandler,或者当它轮询传出数据时它使用 ITcpEventHandler::getOutgoingData

我的类 HttpClient 使用 TcpConnection(聚合)并将自身传递给 TcpConnection 构造函数,并在这些接口(interface)方法中进行处理。

所以 TcpConnection 必须实现这些方法,但我不希望使用 HttpClient 的用户直接访问 ITcpEventHandler 方法(传入数据获取传出数据)。他们不应该能够直接调用 incomingDatagetOutgoingData

希望这能澄清我的用例。

最佳答案

使用 protected 派生使得基类的成员无法通过指向派生类的指针访问,并且不允许隐式转换。

在我看来,你想要的不是禁止通过基类(接口(interface))访问,而是禁止通过派生类(具体实现)访问:

class IHandler
{
public:
virtual int process_input(char input) = 0; //pure virtual
virtual std::string name() { return "IHandler"; } //simple implementation
};

class MyEngine : public IHandler
// ^^^^^^
{
protected: // <== Make the functions inaccessible from a pointer
// or reference to `MyEngine`.

virtual int process_input(char input) { return 0; } //override pure virtual
using IHandler::name; //use IHandler version
};

在这里,在派生类中,您基本上覆盖了 process_input 函数的可见性,以便客户端只能通过指针或对基类的引用来调用它们。

这样你就可以做到:

MyEngine* ptr = new MyEngine();
ptr->process_input('a'); // ERROR!
std::cout << ptr->name(); // ERROR!

但这将是可能的:

IHandler* ptr = new MyEngine();
ptr->process_input('a'); // OK
std::cout << ptr->name(); // OK

关于C++ - 允许通过基类(接口(interface))访问,禁止通过派生类(具体实现)访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15571044/

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