C++ 具有数据成员的抽象基类

C++ 具有数据成员的抽象基类,c++,C++,如果我要创建一个抽象基类,并且从它派生的类将有一些相同的数据成员,那么在抽象基类中使这些成员私有并对其提供受保护的访问是更好的做法吗?或者不必麻烦,只需将数据成员放在派生类中。这是在C++中。 如何使成员私有,并提供受保护的访问?< /P> 派生类无法访问基类的私有成员。 派生类A和派生类B都需要您正在谈论的那些数据成员吗?如果是,则将它们放在基类中,并使其受保护 我知道,我真的想发表评论,但我不知道怎么做。可能我需要更多的声誉?在基类中包含一些数据(以及实现,即方法)没有什么错 基类可以是虚拟

如果我要创建一个抽象基类,并且从它派生的类将有一些相同的数据成员,那么在抽象基类中使这些成员私有并对其提供受保护的访问是更好的做法吗?或者不必麻烦,只需将数据成员放在派生类中。这是在C++中。

如何使成员私有,并提供受保护的访问?< /P> 派生类无法访问基类的私有成员。 派生类A和派生类B都需要您正在谈论的那些数据成员吗?如果是,则将它们放在基类中,并使其受保护


我知道,我真的想发表评论,但我不知道怎么做。可能我需要更多的声誉?

在基类中包含一些数据(以及实现,即方法)没有什么错

基类可以是虚拟的,仅仅因为它的一个方法必须在派生类中实现。决定将这些变量和方法(基类的)私有化、保护化甚至公开化是一个逐案的问题


例如,基类可以有一个公共方法、一个受保护的方法和/或数据以及一些私有方法。

如果数据属于派生类,则让派生类执行它想要包含该数据的操作

通过将该数据放置在基类中(而不是私下),可以强制每个派生类都拥有它。例如,除非派生类需要填写数据成员,否则不应强制它们执行任何操作。基类定义派生类必须做什么,而不是它们应该如何做

如果您发现可能存在一个公共主题,那么可以创建一个包含这些成员和实现的派生类,然后将其作为希望使用它的人的基类。例如:

struct car
{
    virtual ~car(){}

    virtual unsigned year(void) const = 0;
    virtual const std::string make(void) const = 0;
}

// Dodge cars can feel free to derive from this instead, it's just a helper
struct dodge_car
{
    virtual ~car(){}

    virtual unsigned year(void) const = 0;

    const std::string make(void) const
    {
        static const std::string result = "Dodge";
        return result;
    }

}
等等。但是你看,任何派生类仍然可以选择实现整个car接口。这也提高了代码的清洁度。通过使您的接口保持真实的接口,实现细节将不会成为阻碍


基类使用的任何变量都应该是私有的,因为派生类不需要知道它是如何工作的,就像派生类的用户不需要知道派生类的内部是如何工作的一样。

不要考虑某些派生类会做什么,想想它们都必须做什么,在编写基类时。换句话说,考虑基类本身及其接口的保证

C++没有单独的“接口定义”概念,只是为此重用了类。(或者在模板中键入duck。)因此,在编写抽象接口类时要小心,以免对实现施加限制


我不回答是或否,因为你没有提供足够的信息,答案取决于其他细节;但是,如果您遵循我简要介绍的指导原则,您的状态会很好。

在OOP设置中,要问的主要问题是:这些数据属于哪里?

在继承关系中,数据(和功能)应该在其或多或少不变的最高阶段定义。这促进了最大程度的模块化和代码重用。例如,假设有两个类:

        class Human;
        class Student : public Human;
在添加数据成员“m_Arms”时,我们根据以下问题确定“Human”级别是定义数据、其用法及其对派生类的可见性的最佳位置:

  • 人类的特化需要人类手臂或多或少的不变行为吗?i、 e.他们能做一些“普通”人类通常不能做的事情吗(确定公共数据)
  • 学生(或其他可能的人类专业)是否需要直接访问它?(确定对子类的可见性)
  • 如果可见,哪些功能是常见的?(确定相关的公共功能)
  • 应该从基类的角度考虑上下文——即使有一个额外的is-a-Human类可以做额外的事情,那么它也需要访问数据。e、 如果出于某种原因,你决定将机器人战警列为“公众人物”,你需要直接进入他的大腿,将枪存放在里面。在这种架构下,大腿需要对所有人类子类可见

    该体系结构可以使用相同的数据模块化、功能模块化和可见性原则进行优化。例如,在定义Robocop类时,可以进一步提取基类Human,如下所示,以允许可见性的更改以及随后的功能更改

        class Human;
        class NormalHuman : public Human; //declare Thigh private here.
        class SuperHuman : public Human; //continue using Thigh as protected.
    

    此外,ARM本身可能具有多态性,允许(请原谅意外的异位解释)基于工厂的架构使用人体部件模块化组装不同类型的人。

    这不是答案。也许你是想发表评论?:)他可能有,除了声誉低于50的成员不能发表评论。每个派生类都会有这些数据成员,并且需要它们。我知道数据成员需要是私有的,但假设每个派生类都有这些数据成员,我假设我也应该提供受保护的访问权限。我仍然建议将基类设置为纯抽象类,然后提供一个帮助类。如果您的设计有任何变化,您不必担心将这些成员强制到新类上,他们只需使用纯抽象类。FWIW,尽可能少的工作来获得正确的虚拟DTOR将占用与注释一样多的空间。我可能会使用强制成员来实现ABC,这仅仅是因为a)我知道派生的类将始终具有这些数据成员,b)我是唯一一个处理代码的人,并且可能会修改代码。然而,这是一个非常有用的建议,如果我将来遇到这样的情况,我可以这样做