C++使用将在派生构造函数中构造的参数调用基构造函数

发布于 2024-10-14 12:13:58 字数 475 浏览 6 评论 0原文

问题 1)

class Base {
    Base(std::string name);

    virtual std::string generateName();
}

class Derived : Base {
    Derived();

    virtual std::string generateName();
}

问题来了:

generateName() 上将调用什么方法?

Derived :: Derived : Base(generateName()) {
    //what method will be called on generateName() ? 
}

问题2)

我应该怎么做?如果默认构造函数必须接受参数,但我需要在派生构造函数中生成该参数?

QUESTION 1)

class Base {
    Base(std::string name);

    virtual std::string generateName();
}

class Derived : Base {
    Derived();

    virtual std::string generateName();
}

here comes the question :

what method will be called on generateName() ?

Derived :: Derived : Base(generateName()) {
    //what method will be called on generateName() ? 
}

QUESTION 2)

how should i make it? if the default constructor must accept a parameter, but i need to generate that parameter in the Derived constructor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薆情海 2024-10-21 12:13:58

首先,解决方案:使用静态成员函数或非成员函数。

至于行为,将调用 Derived::generateName()。 C++ 标准中定义此行为的长句说道 (C++03 12.7/3):

当从构造函数(包括数据成员的 mem-initializer)或析构函数直接或间接调用虚拟函数,并且调用适用的对象是正在构造或销毁的对象时,该函数被调用的是构造函数中定义的或者
析构函数自己的类或其基类之一,但不是在从构造函数或析构函数的类派生的类中重写它的函数,也不是在最派生对象的其他基类之一中重写它的函数。

由于虚拟调用时执行的构造函数是 Derived 构造函数,因此会调用 Derived::generateName()

现已删除的答案正确地引用了 Scott Meyers 的一篇文章,该文章建议“在构造或过程中切勿调用虚拟函数”销毁。” 调用覆盖者的规则非常复杂且难以记住。

First, the solution: use a static member function or a nonmember function.

As for the behavior, Derived::generateName() will be called. The long sentence in the C++ Standard that defines this behavior says (C++03 12.7/3):

When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or
destructor's own class or in one of its bases, but not a function overriding it in a class derived from the constructor or destructor's class, or overriding it in one of the other base classes of the most derived object.

Because the constructor being executed at the time of the virtual call is the Derived constructor, Derived::generateName() is called.

A now-deleted answer rightly referred to an article by Scott Meyers that recommends "Never Call Virtual Functions during Construction or Destruction." The rules for what overrider gets called are complex and difficult to remember.

无名指的心愿 2024-10-21 12:13:58

采取两个...

我在基类初始化程序和两个构造函数中调用了 generateName() 进行了一次运行。输出让我感到困惑:

Derived (called from Derived's Base initializer)
Base    (called from Base ctor)
Derived (called from Derived ctor)

我从未想象过一个类可以在单个构造序列中从派生类转变为基类,然后又变回派生类。你每天都会学到新东西。

Take two...

I did a run with calls to generateName() in the base class initialiser and both constructors. The output left me nonplussed:

Derived (called from Derived's Base initializer)
Base    (called from Base ctor)
Derived (called from Derived ctor)

I never imagined that a class could morph from being a derived to a base, then back to a derived in a single construction sequence. You learn something new every day.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文