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,否则继承机制就没用了。
我想了解以下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,否则继承机制就没用了。