在 C++ 中调用抽象基类的构造函数

2 c++ inheritance constructor class c++11

我知道如果我有一个抽象类,那么我无法创建抽象类类型的对象。但假设“Base”是基类,“Derived”是派生类。在基类中,我有一个成员变量名称。

Base.h
Base(string name = "");

Base.cpp
Base(string theName){name = theName);
Run Code Online (Sandbox Code Playgroud)

这不是创建一个对象吗?

在派生类中,我有成员变量age。现在在派生类的默认构造函数中

Derived.h
Derived(string name = "", int theAge = 0);

Derived.cpp
Derived(string theName, int theAge):Base(theName) { age = theAge }
Run Code Online (Sandbox Code Playgroud)

这不是也调用了 Base 的默认构造函数吗?那么,我是否可以调用参数化构造函数但不能调用默认构造函数?

另一件事,如果我在基类中除了纯函数之外还有另一个函数,如果不允许为基类创建对象,我如何调用该函数?

提前致谢!

Chr*_*ckl 8

\n

我知道如果我有一个抽象类,那么我无法创建抽象类类型的对象。

\n
\n\n

但有一个例外:抽象类的对象可以创建为派生类对象的子对象。

\n\n

事实上,它必须在这种情况下创建,因为这就是继承在 C++ 中的工作原理。派生类的对象包含基类的对象(或者通常是基类的对象,因为我们不要忘记 C++ 也支持多重继承)。

\n\n

标准在 \xc2\xa710.4/1 中说得很清楚:

\n\n
\n

抽象类是只能用作其他类的基类的类;不能创建抽象类的任何对象,除非作为派生类的子对象。

\n
\n\n

现在你已经知道了:抽象类的实例可能存在于这个限制之内。所以,

\n\n
\n
Base(string theName){name = theName);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这不是创建一个对象吗?

\n
\n\n

它是一个像其他构造函数一样的构造函数;它用于创建一个对象。考虑到上述规则,类是抽象的这一事实并不重要。

\n\n
\n
Derived(string theName, int theAge):Base(theName) { age = theAge }\n
Run Code Online (Sandbox Code Playgroud)\n\n

这不是也调用了 Base 的默认构造函数吗?

\n
\n\n

是的。

\n\n
\n

那么,我是否可以调用参数化构造函数但不能调用默认构造函数?

\n
\n\n

所有参数均默认的构造函数默认构造函数。

\n\n
\n

另一件事,如果我在基类中除了纯函数之外还有另一个函数,如果不允许为基类创建对象,我如何调用该函数?

\n
\n\n

如果它是一个public函数,那么任何拥有派生类对象的人都可以调用它(包括派生类本身)。此外,任何通过基类的指针或引用访问派生类对象的人都可以调用它。当然,基类本身也可以调用它。

\n\n

如果它是一个protected函数,则派生类和潜在的进一步派生类可以调用它。

\n\n

如果是private,则基类本身可以调用它。

\n\n

正如我们上面所确定的,从技术上讲,您确实为基类创建一个对象,作为派生类对象内部的子对象。因此,原则上,这种情况并不特殊,因为基类是抽象的。

\n\n
\n\n

这里要记住的是,该语言的技术细节是经过定义的,以便所有基本的面向对象功能都能按预期工作。您在日常编程业务中不必担心这些事情。

\n