如何在派生类中声明复制构造函数,而基类没有默认构造函数?

19

请看下面的例子:

class Base
{
protected:
    int m_nValue;

public:
    Base(int nValue)
        : m_nValue(nValue)
    {
    }

    const char* GetName() { return "Base"; }
    int GetValue() { return m_nValue; }
};

class Derived: public Base
{
public:
    Derived(int nValue)
        : Base(nValue)
    {
    }
    Derived( const Base &d ){
        std::cout << "copy constructor\n";
    }

    const char* GetName() { return "Derived"; }
    int GetValueDoubled() { return m_nValue * 2; }
};

这段代码一直抛出一个错误,说基类没有默认构造函数。当我声明它时,一切正常。但是当我没有声明时,代码就无法工作。

如何在派生类中声明复制构造函数而不声明基类的默认构造函数?

谢谢。


3
编译器在存在任何参数化构造函数时不会为类提供默认构造函数。 - Amit
3个回答

29

调用基类的复制构造函数(由编译器生成):

Derived( const Derived &d ) : Base(d)
{            //^^^^^^^ change this to Derived. Your code is using Base
    std::cout << "copy constructor\n";
}

理想情况下,你应该调用基类生成的复制构造函数。不要考虑调用其他构造函数,我认为那会是一个坏主意。


2
@amit:Base(Base const&)将由编译器生成! - Nawaz
2
@amit:当然是的。除非你自己定义了一个复制构造函数,否则编译器会为你合成一个。 - PlasmaHH

5

您可以(并且应该)调用基类的复制构造函数,例如:

Derived( const Derived &d ) :
        Base(d)
{
    std::cout << "copy constructor\n";
}

请注意,我将Base参数转换为Derived参数,因为只有这样才被称为复制构造函数。但是也许你并不真正需要一个复制构造函数...

1
Base(Base const&) 是由编译器生成的。 - James Kanze
@amit:当然是的。除非你自己定义了一个复制构造函数,否则编译器会为你合成一个。 - PlasmaHH
@PlasmaHH:你应该在你的回答中明确提到它,我完全忘记了:\ - amit
@amit:答案中没有明确提到的许多其他基本事项,因为它们与问题无关,要么我解释所有这些事项,要么就不解释。我认为在这里不解释更有用。 - PlasmaHH

-1

如果类类型(结构体、类或联合体)没有提供任何形式的用户声明的构造函数,编译器将始终声明一个默认构造函数和一个非显式的拷贝构造函数作为其类的内联公共成员。

如果存在一些用户声明的构造函数,则用户仍然可以通过使用关键字“default”强制编译器自动生成默认构造函数,否则会隐式地声明。

在基础构造函数中,您需要使用用户声明的构造函数声明否则使用关键字“default”声明。

class Base
{
protected:
    int m_nValue;

public:
    Base(const Base&) = default;    // since cpp11

    Base(int nValue)
        : m_nValue(nValue)
    {
    }

    const char* GetName() { return "Base"; }
    int GetValue() { return m_nValue; }
};

在派生类的构造函数中,你必须像这样构造基本构造函数:
Derived(const Base &d)
: Base(d)
{
    std::cout << "copy constructor\n";
}

3
这似乎对现有的八年前的答案没有任何补充,也没有更正复制构造函数的参数。 - Asteroids With Wings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接