你能强制从抽象基础 class 继承的 classes 只在基础案例中定义 public 方法吗?

Can you force classes inheriting from abstract base class to only have the public methods defined in base case?

是否可以有一个抽象 class 但强制执行 classes 以仅具有抽象 class 中的 public 方法?

我不关心私有方法如何工作,但我想强制 classes 只有一个 public 方法。

例如,假设我有以下摘要 class:

class MyObjectTransform
{
    public:
    virtual ~MyObjectTransform()
    {
    }

    virtual MyObject transform(MyObject input) = 0;
};

然后我想强制所有从 MyObjectTransform 继承的对象只有一个(构造函数除外)public 方法,transform。我不在乎继承 classes 有什么私有方法。这可能吗?

更新: 这里的目标是强制开发人员仅通过单一方法公开功能。例如,考虑这种情况:

class ATransform
{
private:
        MyObject A_Stuff(MyObject input);

public:
    override MyObject transform(MyObject input)
    {
        return this->A_stuff(input);
    }
};

class BTransform
{
public:
    MyObject B_Stuff(MyObject input);

    override MyObject transform(MyObject input)
    {
        return this->B_stuff(input);
    }
};

这里的问题是开发者可以直接调用B_Stuff。我想阻止这种情况。

不,你不能。 Derived 类 可以定义任何他们想要的 public 成员函数。没有办法对此加以限制。

更新:

如果您不希望用户访问它,请将 B_Stuff 声明为 私有。将其声明为 protected 如果您希望从 BTransform 派生的 类 也可以使用它。

class BTransform
{
private:
    MyObject B_Stuff(MyObject input);

Public:     
    override MyObject transform(MyObject input)
    {
        return this->B_stuff(input);
    }
};

但是您不能强制使用 C++ 语言将 B_Stuff 声明为私有或受保护。它必须被定义为一个策略。

您已经在使用适用于此场景的机制:它是抽象基础 class!

它的全部要点是,此层次结构中的所有 classes 都旨在支持通过 pointer/reference 到基础 class MyObjectTransform 的多态使用。这样用户就不知道实现 class 有什么 public 方法,因为他只能使用通过基础 class 可用的方法:transform

如果您想更严格地执行此操作,请完全不要在 header 中公开实现 classes 的声明。隐藏 BTransformATransform,并仅公开工厂函数以及抽象基础 class。

std::unique_ptr<MyObjectTransform> makeATransform()
{
    return { new ATransform };
}

std::unique_ptr<MyObjectTransform> makeBTransform()
{
    return { new BTransform };
}

这样 client/developer 代码如下所示:

int main()
{
    auto btransform = makeBTransform();

    btransform->B_Stuff(input);   // ERROR, MyObjectTransform doesn't have this member function.
    btransform->transform(input); // FINE
}

用户只能使用基础class中的一种public方法。

当然有人可以将指针指向 BTransform*,然后做任何他们想做的事情(前提是他们能找出 BTransform 的实际实现是什么,因为我们隐藏了它)。但是没有绕过这样一个事实,即要阻止 public 方法可访问,您必须使它们成为 private,就像 chmike 所写的那样。正如 Herb Sutter 所说:

C++ protects against Murphy, not Machiavelli

在 C++ 中,public 函数应该是非虚函数,而虚函数应该是私有的(析构函数除外)。应用此 guideline 会使您的问题完全消失,因为只剩下一个 public 函数供 class 的客户调用:

class MyObjectTransform
{
    public:
    virtual ~MyObjectTransform()
    {
    }

    MyObject transform(MyObject input) // non-virtual!
    {
        // can do extra stuff, e.g. check input for validity
        doTransform(input);
    }

    private:
    virtual MyObject doTransform(MyObject input) = 0;
};

class ATransform : public MyObjectTransform
{
private:
    MyObject A_Stuff(MyObject input);

     MyObject doTransform(MyObject input) override
    {
        return this->A_Stuff(input);
    }
};

class BTransform : public MyObjectTransform
{
private:
    MyObject B_Stuff(MyObject input);

    MyObject doTransform(MyObject input) override
    {
        return this->B_Stuff(input);
    }
};