【问题标题】:How to declare copy constructor in derived class, without default construcor in base?如何在派生类中声明复制构造函数,而基类中没有默认构造函数?
【发布时间】:2012-02-16 10:26:24
【问题描述】:

请看下面的例子:

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; }
};

此代码不断向我抛出一个错误,即基类没有默认构造函数。当我宣布一切正常时。但是当我不这样做时,代码不起作用。

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

感谢。

【问题讨论】:

  • 一旦我们有任何参数化的构造函数,编译器就不会为类提供默认构造函数..

标签: c++ inheritance copy-constructor


【解决方案1】:

调用base的copy-constructor(由编译器生成):

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

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

【讨论】:

  • @amit: Base(Base const&amp;) 将由编译器生成!
  • @amit:当然是。除非你自己定义一个拷贝 ctor,否则编译器会为你合成一个。
【解决方案2】:

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

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

请注意,我将 Base 参数转换为 Derived 参数,因为只有它称为复制 ctor。但也许你并不是真的想要一个复制 ctor...

【讨论】:

  • Base(Base const&amp;) 是。由编译器。
  • @amit:当然是。除非你自己定义一个拷贝 ctor,否则编译器会为你合成一个。
  • @PlasmaHH:您应该在回答中明确提及,我完全忘记了:\
  • @amit:还有很多其他基本的东西没有在答案中明确提到,因为它们与问题无关,要么我解释所有这些,要么没有。我认为这里没有比这更有用的了。
【解决方案3】:

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

如果存在一些用户声明的构造函数,用户仍可以强制编译器自动生成默认构造函数,否则该构造函数将使用关键字 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";
}

【讨论】:

  • 这似乎没有对现有的八岁答案增加任何内容;它也不能更正复制 ctor 参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
  • 2013-06-23
  • 1970-01-01
  • 2016-07-19
  • 2020-09-22
  • 2018-07-21
  • 1970-01-01
相关资源
最近更新 更多