Copyable and non-copyable Objects in C++

In C++, objects can be categorized as either copyable or non-copyable based on whether they can be copied or assigned using the copy constructor and copy assignment operator. The copyability of an object is determined by the presence or absence of these copy operations.

  1. Copyable Objects: Copyable objects can be copied and assigned using the copy constructor and copy assignment operator. By default, user-defined types in C++ are copyable unless specific measures are taken to disable or restrict copying. When an object is copied, a new object is created with the same state as the original object. Example of a copyable class:
    
    class Copyable {
    public:
        Copyable() {}
        Copyable(const Copyable& other) {}
        Copyable& operator=(const Copyable& other) { return *this; }
    };
    
  2. Non-Copyable Objects: Non-copyable objects cannot be copied or assigned using the copy constructor and copy assignment operator. This is often intentional when dealing with resources that should not be shared or when the semantics of copying do not make sense for a particular type. Example of a non-copyable class:
    
    class NonCopyable {
    public:
        NonCopyable() {}
    private:
        NonCopyable(const NonCopyable& other) = delete;
        NonCopyable& operator=(const NonCopyable& other) = delete;
    };
    
    In the example above, the copy constructor and copy assignment operator are explicitly marked as delete, preventing any attempts to copy or assign objects of the NonCopyable class.Alternatively, the non-copyability can be achieved by making the copy constructor and copy assignment operator private without providing any implementation. This prevents their usage by making them inaccessible outside the class.
    
    class NonCopyable {
    public:
        NonCopyable() {}
    private:
        NonCopyable(const NonCopyable& other);
        NonCopyable& operator=(const NonCopyable& other);
    };
    
    In both cases, attempting to copy or assign a non-copyable object will result in a compilation error.

By explicitly specifying or disabling the copy constructor and copy assignment operator, you can control the copyability of objects in your C++ code. This allows you to enforce object ownership semantics, prevent unintended sharing of resources, and ensure proper handling of sensitive data or non-copyable resources.

Is it possible to create copy of the derived class if base class is non-copyable?
No, it is not possible to create a copy of a derived class if the base class is non-copyable. When the base class is non-copyable, it means that its copy constructor and copy assignment operator are either deleted or declared as private and not accessible outside the class. As a result, the derived class, which inherits from the non-copyable base class, cannot invoke the base class's copy operations to perform a copy.

In C++, the copy constructor of a derived class invokes the copy constructor of its base class to copy the base class sub-object. If the base class is non-copyable, the derived class cannot properly perform the copy operation.

Consider the following example:

class Base {
public:
    Base() {}
private:
    Base(const Base& other) = delete;
    Base& operator=(const Base& other) = delete;
};

class Derived : public Base {
public:
    Derived() {}
};

int main() {
    Derived d1;
    Derived d2 = d1;  // Error: Attempting to copy non-copyable base class 'Base'
    return 0;
}
In this example, the Base class is non-copyable, and the Derived class inherits from it. When attempting to create a copy of the Derived object d1 by initializing d2 with d1, a compilation error occurs. The error arises because the copy constructor of Derived implicitly invokes the copy constructor of Base, which is deleted.

To enable copying of derived classes, the base class needs to be copyable. If the base class cannot be made copyable, one alternative is to provide custom copy operations or use other techniques like move semantics to achieve the desired behavior.

Comments

Popular posts from this blog

C++ data structure and containers and their operation with time complexity

Prepare for your next C++ interview