我想了解以下c++概念。Class_a是抽象类,根据抽象类的概念,我们不能创建它的任何实例。我也使用过初始化列表和抽象类,但从未使用过以下概念。在代码中,对class_b、class_a的初始化列表进行了初始化。我想了解是什么意思initlizing initilization列表。
class_b::class_b(int val):nameA::class_a()
在fileA.cpp
namespace nameA
{
class class_a
{
public:
virtual ~class_a(){};
virtual void process()=0;
};
}
in fileb.h file
namespace nameB
{
class class_b : public nameA::class_a
{
public:
class_b(int val);
}
}
在file .cpp文件
namespace nameB
{
class_b::class_b(int val)
:nameA::class_a() //Want to understand this line...
}
用一个稍微丰富一点的例子会更清楚。因为如果抽象基类既没有属性也没有方法,就很难看出如何初始化它。
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;
}
这里的抽象类持有一个属性,该属性将对子类可用。这个属性必须在构造时设置因为它没有公共setter。语言必须提供一种初始化抽象子类的方法,这意味着不是构建一个对象,而是初始化子对象——这里设置名称。
通过派生,每个class_b对象都将包含一个class_a子对象。
即使你不能instanciate class_a类型的一个对象,有可能需要初始化这个对象。考虑一个抽象类也可以有成员。
如果你有一个抽象类的接口(如Java),这个抽象类显然不需要初始化。然而,它会在c++中获得一个(空的)默认构造函数,您可以在初始化列表中显式调用它。(如果你不显式调用它,它将被隐式调用)
如果类是抽象的,并不意味着它不能有任何构造函数。这意味着你不能用它来创建一个独立的对象。
这是经典的继承机制:- 您正在创建
child_class
对象 - 调用
child_class()
构造器 child_class()
构造函数调用base_class()
构造函数以保证base_class
的字段被正确构建- 然后对其余的
child_class
字段执行child_class()
构造函数
在您的示例中,您自己调用class_a()
构造函数,但无论如何都会调用它。总之,这不是抽象类的问题,而是简单继承的问题。
如果class_a
字段存在,你需要有一些机制来初始化它们,这就是为什么你可以调用class_a()
构造函数,即使它是抽象类,否则继承机制就没用了。