Варианты реализации конструктора копирования и оператора присваивания-

Недавно я пересматривал конструктор копирования, оператор присваивания, идентификацию подкачки копирования, которую можно увидеть здесь : . Что такое копия -и -подкачки идиомы? и многие другие места-

Ссылка выше — отличный пост -, но у меня осталось еще несколько вопросов -Ответы на эти вопросы есть во множестве мест, на stackoverflow и многих других сайтах, но я не видел большой согласованности-

1 -Если у вас естьtry-catchвокруг областей, где мы выделяем новую память для глубокой копии в конструкторе копирования? (Я видел и то, и другое)

2 -Что касается наследования как для конструктора копирования, так и для оператора присваивания, когда следует вызывать функции базового класса, а когда эти функции должны быть виртуальными?

3 -Является ли std::copyлучшим способом дублирования памяти в конструкторе копирования? Я видел это с memcpy, и видел, как другие говорят memcpyхудшее, что есть на земле.


Рассмотрим пример Ниже (Спасибо за все отзывы ), они вызвали некоторые дополнительные вопросы:

4 -Должны ли мы проверять самоназначение? Если да, то где

5 -Вопрос не по теме, но я видел, что swapped используется как: std::copy(Other.Data,Other.Data + size,Data); должно ли быть: std::copy(Other.Data,Other.Data + (size-1),Data); если своп идет от «первого к последнему», а 0-й элемент - это Other.Data?

6 -Почему не работает закомментированный конструктор (Пришлось изменить размер на mysize)-предполагается, что это означает, что независимо от порядка, в котором я их пишу, конструктор всегда будет сначала вызывать элемент распределения?

7 -Любые другие комментарии по моей реализации? Я знаю, что код бесполезен, но я просто пытаюсь проиллюстрировать это.

class TBar
{

    public:

    //Swap Function        
    void swap(TBar &One, TBar &Two)
    {
            std::swap(One.b,Two.b);
            std::swap(One.a,Two.a);
    }

    int a;
    int *b;


    TBar& operator=(TBar Other)
    {
            swap(Other,*this);
            return (*this);
    }

    TBar() : a(0), b(new int) {}                //We Always Allocate the int 

    TBar(TBar const &Other) : a(Other.a), b(new int) 
    {
            std::copy(Other.b,Other.b,b);
            *b = 22;                                                //Just to have something
    }

    virtual ~TBar() { delete b;}
};

class TSuperFoo : public TBar
{
    public:

    int* Data;
    int size;

    //Swap Function for copy swap 
    void swap (TSuperFoo &One, TSuperFoo &Two)
    {
            std::swap(static_cast(One),static_cast(Two));
            std::swap(One.Data,Two.Data);
            std::swap(One.size,Two.size);
    }

    //Default Constructor
    TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[mysize]) {}
    //TSuperFoo(int mysize = 5) : TBar(), size(mysize), Data(new int[size]) {}                *1

    //Copy Constructor
    TSuperFoo(TSuperFoo const &Other) : TBar(Other), size(Other.size), Data(new int[Other.size])        // I need [Other.size]! not sizw
    {
            std::copy(Other.Data,Other.Data + size,Data);        // Should this be (size-1) if std::copy is First -> Last? *2
    }

    //Assignment Operator
    TSuperFoo& operator=(TSuperFoo Other)
    {
            swap(Other,(*this));
            return (*this);
    }

    ~TSuperFoo() { delete[] Data;}

};

6
задан Community 23 May 2017 в 12:27
поделиться