Abstract class 初始化列表中的init

Abstract class init in the initialization list

我想了解以下c++概念。 class_a 是抽象的 class 并且根据抽象的 class 概念我们不能创建它的任何实例。 我也使用了初始化列表和摘要 class 但从未使用过以下概念。 代码中初始化了class_b、class_a的初始化列表。我想了解在初始化列表中初始化它是什么意思。

 class_b::class_b(int val):nameA::class_a()

在fileA.cpp

namespace nameA
{
class class_a
{
    public:
        virtual ~class_a(){};
        virtual void process()=0;
};
}

在 fileb.h 文件中

namespace nameB
{
class class_b  : public nameA::class_a
{
    public:
    class_b(int val);
}
}

在 fileb.cpp 文件中

namespace nameB
{
class_b::class_b(int val)
:nameA::class_a() //Want to understand this line...
}

通过推导,每个class_b对象将包含一个class_a子对象。

即使无法实例化class_a类型的对象,也可能需要初始化此子对象。考虑一个抽象 class 也可以有成员。

如果你有一个接口方面的抽象class(比如Java),这个抽象class显然不需要初始化。尽管如此,它会在 C++ 中获得一个(空的)默认构造函数,您可以在初始化列表中显式调用它。 (如果不显式调用,会隐式调用。)

稍微丰富一点的例子会更清楚。因为如果抽象基 class 既没有属性也没有方法,那么很难看出如何初始化它。

class NamedProcessor {
    std::string name;    // a private attribute
public:
    NamedProcessor(const std::string &name) : name(name) {}
    virtual ~NamedProcessor() {}

    // a pure virtual method to make the class abstract
    virtual void process() = 0;

    std::string getName() {
        return name;
    }
};

class Doubler : public NamedProcessor {
    int value;           // a private attribute

public:
    Doubler(int initial = 1) : NamedProcessor("Doubler") {
        reset(initial);
    }

    void reset(int initial) {
        value = initial;
    }

    int getValue() {
        return value;
    }

    // the concrete implementation
    void process() {
        value *= 2;
    }
};

int main() {
    // Compiler would croak witherror : variable type 'NamedProcessor' is an abstract class
    // NamedProcessor wrong("Ill formed");

    Doubler doubler;
    std::cout << doubler.getName() << "\n";     // name has been initialized...
    return 0;
}

这里的抽象 class 包含一个属性,子classes 可以使用该属性。而且这个属性必须在构造时设置,因为没有public setter 给它。该语言必须提供一种方法来初始化抽象子class,意思不是构建一个对象,而是初始化一个子对象——这里设置名称。

如果class是抽象的,并不意味着它不能有任何构造函数。这意味着你不能用它来创建一个独立的对象。

所以这里是classic继承机制:

  • 您创建了一个 child_class 对象
  • 它调用了一个child_class()构造函数
  • child_class() 构造函数调用 base_class() 构造函数来保证 base_class 的字段构建正确
  • 然后为其余child_class个字段执行child_class()构造函数

在您的示例中,您自己调用了 class_a() 构造函数,但无论如何都会调用它。所以总而言之,这不是抽象class,而是简单的继承。

你需要有一些机制来初始化 class_a 字段(如果它们存在),这就是为什么你可以调用 class_a() 构造函数,即使它是抽象的 class,否则继承机制就没用了。