使用“using”关键字继承基类的复制和移动构造函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用“using”关键字继承基类的复制和移动构造函数相关的知识,希望对你有一定的参考价值。

我想使用using关键字继承基类的复制构造函数:

#include <iostream>

struct A
{
    A() = default;

    A(const A  &) { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
    A(      A &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; }

    A& operator=(const A  &) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
    A& operator=(      A &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
};

struct B : A
{
    using A::A;
    using A::operator=;

    B& operator=(const B  &) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
    B& operator=(      B &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
};

int main()
{
    A a;
    B b;
    b = a; // OK
    B b1(          a ); // compile error
    B b2(std::move(a)); // compile error
    return 0;
}

使用using关键字继承赋值运算符可以正常工作,但继承复制和移动构造函数会导致编译错误:继承的构造函数不是从相同或派生类型的表达式初始化的候选者。

http://coliru.stacked-crooked.com/a/fe84b429c391c894

main.cpp:16:14: note:   an inherited constructor is not a candidate for initialization from an expression of the same or derived type
main.cpp:8:5: note: candidate: A::A(A&&)
     A(      A &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
     ^
main.cpp:16:14: note:   inherited here
     using A::A;

为什么我可以继承赋值运算符但不能继承复制构造函数?有什么区别?我能理解我是否也无法继承赋值运算符。但是相反继承赋值运算符被认为是可以的。这对我来说有点奇怪。

故事

我想要的是类似于this问题中的问题:我想在不修改它的情况下向现有类添加新方法(它是来自另一个库的类)。

http://coliru.stacked-crooked.com/a/149a6194717cd465

#include <iostream>

struct A // not my class
{
};

struct B : A
{
    using A::A;
    using A::operator=;

    void foo() { std::cerr << "fuu" << std::endl; }
};

A NotMyFunc()
{
    return {};
}

int main()
{
    B b(NotMyFunc());
    b.foo();
    return 0;
}

但我不想重新实现复制和移动构造函数。

答案

你需要一个B的构造函数,它有一个A作为参数。然后,您需要使默认构造函数显式。

struct B : A
{
    using A::A;
    using A::operator=;

    B() = default;
    B(const A& a) : A(a) {}
    B(A &&a): A(std::move(a)) {}
};

以上是关于使用“using”关键字继承基类的复制和移动构造函数的主要内容,如果未能解决你的问题,请参考以下文章

使用“using”关键字继承基类的复制和移动构造函数

使用 C++ 基类构造函数?

scala_类的继承

C# 使用new 关键字显式隐藏从基类继承的成员和内部类的使用

关于C++基类与派生类

面向对向之继承和扫描顺序