Конструктор копирования неявно удаляется, так как определение по умолчанию будет некорректным

У меня есть класс A (из библиотеки, над которой у меня нет контроля) с конструктором частной копии и ---- +: = 1 =: + ---- и класс clone, полученный из B. Я хотел бы реализовать A для clone а также.

Наивный подход

 B

однако не удается, так как конструктор копирования #include <memory> class A { // I have no control here public: A(int a) {}; std::shared_ptr<A> clone() const { return std::shared_ptr<A>(new A(*this)); } private: A(const A & a) {}; }; class B: public A { public: B(int data, int extraData): A(data), extraData_(extraData) { } std::shared_ptr<B> clone() const { return std::shared_ptr<B>(new B(*this)); } private: int extraData_; }; int main() { A a(1); } является личным:

A

Возможно, есть способ использовать main.cpp: In member function ‘std::shared_ptr<B> B::clone() const’: main.cpp:27:42: error: use of deleted function ‘B::B(const B&)’ return std::shared_ptr<B>(new B(*this)); ^ main.cpp:17:7: note: ‘B::B(const B&)’ is implicitly deleted because the default definition would be ill-formed: class B: public A { ^ main.cpp:14:5: error: ‘A::A(const A&)’ is private A(const A & a) {}; ^ main.cpp:17:7: error: within this context class B: public A { для A::clone(), но я не уверен, как именно это будет работать. Есть намеки?

7 голосов | спросил Nico Schlömer 5 J0000006Europe/Moscow 2015, 14:19:37

3 ответа


0

Полагаю, это опечатка, из-за которой у вашего B нет открытых участников, и что вам не хватает public: до определения B::B(int,int)

Автор класса, представленный вашим A, очевидно, хочет, чтобы это было клонируемый, но не копируемый Это предполагает, что он или она хочет все экземпляров жить в куче. Но, напротив, есть публика Конструктор A::A(int). Вы уверены, что правы в этом?

Можно предположить, что класс может раскрыть достаточно информации о данном экземпляре, чтобы составить другой экземпляр. Например, положить немного больше плоти от A:

class A {
public:
    A(int a) 
    : data_(a){};

    std::shared_ptr<A>
    clone() const
    {
        return std::shared_ptr<A>(new A(*this));
    }

    int data() const {
        return data_;
    }

private:
    A(const A & a) {};
    int data_;
};

И если это так, то открытый конструктор сделает это просто неудобно обходить закрытый неопределенный конструктор копирования:

A a0(1);
A a1{a0.data()};     // Inconvenient copy construction

Так что я менее чем уверен, что A верно представляет проблему учебный класс. Принимая это за чистую монету, однако, вопрос, на который вам нужно ответить это: Можете ли вы даже неудобно скопировать конструкцию A?

Если нет, то вы застряли. Если это так, то вы можете использовать неудобную копию построение A для явного определения обычного конструктора копирования для B, что все, что вам нужно Например.

class B: public A {
public:
    B(B const & other)
    : A(other.data()),extraData_(other.extraData_){}    

    B(int data, int extraData):
    A(data),
    extraData_(extraData)
    {
    }

    std::shared_ptr<B>
    clone() const
    {
        return std::shared_ptr<B>(new B(*this));
    }

    int extradata() const {
        return extraData_;
    }

private:
    int extraData_;
};

#include <iostream>

int main()
{
    B b(1,2);
    std::shared_ptr<B> pb = b.clone();
    std::cout << pb->data() << std::endl;
    std::cout << pb->extradata() << std::endl;
    return 0;
} 
ответил Mike Kinghan 5 J0000006Europe/Moscow 2015, 22:34:16
0

Необходимо сделать конструктор копирования A защищенным, чтобы его мог использовать производный класс:

protected:
    A(const A & a) { /*...*/ }

Надеюсь, это поможет.

ответил Nawaz 5 J0000006Europe/Moscow 2015, 14:25:05
0

Причина, по которой определение по умолчанию для конструктора копирования B неверна, заключается в том, что - если бы это было разрешено - он вызвал бы приватный (поэтому недоступный для B) и не определенный конструктор копирования A.

Сделайте A конструктором копирования либо защищенным, либо общедоступным, чтобы он был доступен для B. Другой (очень плохой) вариант - объявить класс B как друга A. Для всех возможностей также потребуется указать определение для конструктора копирования A.

ответил Peter 5 J0000006Europe/Moscow 2015, 14:27:03

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132