簡體   English   中英

不要對虛擬基類使用默認構造函數

[英]Not to use default constructor for virtual base class

我當時正在研究理解虛擬基類和構造函數調用,並且我知道最派生的類將直接調用頂級基類的默認構造函數。 但是有沒有一種方法可以不調用頂級基礎默認構造函數呢?

我的問題的一個例子

#include <iostream>
#include <cstdint>

////// BEGIN LIBRARY CODE
class A
{
public:
    A()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }

    A(int)
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

class B : virtual public A
{
public:
    B()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

class C: virtual public A
{
public:
    C()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

class D: public B, public C
{
public:
    D(int x) : A(x), B(), C() // ok. works as expected
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};
////// END LIBRARY CODE


////// USER CODE BEGINS

class E: public D
{
public:
    E() : D(42) // problem, invokes A(), not A(int)
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }

    E(int x) : D(x) // same problem
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};
////// USER CODE ENDS

int main()
{
    D d(1);
    E e1,e2(42);
}

輸出量

A::A(int)
B::B()
C::C()
D::D(int)
A::A()
B::B()
C::C()
D::D(int)
E::E()
A::A()
B::B()
C::C()
D::D(int)
E::E(int)

問題:

我希望E僅關心D構造。 但是從開頭的解釋來看,如果我不在下面添加A::A(int) ,無論我如何更新類D,我將始終使用默認構造函數

E() : A(42), D(42) // works, but undesirable
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

E(int x) : A(x), D(x) // this works, but undesirable
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

簡而言之,我不希望擴展庫代碼class D的用戶代碼class E必須指定class A構造參數,所以...

  • 有什么辦法可以通過繼承鏈中的“中間”類(例如上面的示例中的D類)來完成,從而減輕派生自大多數類的負擔呢?

頂級類的構造函數調用所有虛擬基的構造函數。 但這與為直接非虛擬基礎調用構造函數沒有什么不同:如果您進行顯式構造函數調用,則編譯器將使用此構造函數; 如果不這樣做,它將使用默認構造函數。 因此答案是否定的,如果默認構造函數不合適,則無法避免從E調用A的構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM