Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8552629
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T14:27:56+00:00 2026-06-11T14:27:56+00:00

Trying to resolve error C2248 related to abstract base class using implementation of copy/move

  • 0

Trying to resolve error C2248 related to abstract base class using implementation of copy/move ctors/assignment operators and dtor (Rule of Five) and a few questions come up:

1) Why does the rule of 5, primarily relating to the dtor, apply when the unique_ptr data members are handled automatically? The dtor implementation should be left empty correct, since the unique_ptrs are automatically destroyed once their owners go out of scope?

2) Suppose another class had a member of type std::unique_ptr of a vector of the same type. In order for this class to be copyable, it must have a copy ctor and copy assignment operator that clone the unique_ptr data member? I have seen this solution, but is seems like the original poster just switched over to shared_ptr for the sake of removing the error alone with little consideration of ownership management. Is this the correct strategy?

3) Consider the same case as question 2 above relating to vector of unique_ptr. Should dtor include a call to clear() the vector?

4) The assignment operators for the Derived1 are not correct. But the base class is supposed to have copy and move assignment operators, since it has copy/move ctors (rule of 4/5). These can’t actually be used outside of the class since it is abstract and thus no instances will be assigned. But how do I utilize this code from the derived classes? Each derived class needs to be able to move/copy the base data members and it’s own data members. I’m not sure what to do.

    #include <algorithm>
#include <memory>
#include <vector>
#include <iostream>

class Base{

public:
    Base() : m_subBases(){};

    /*  copy ctor */
    Base(const Base& other) : m_subBases(){
        *this = other;
    };

    /*  move ctor */
    Base(Base&& other) : m_subBases(){
        *this =std::move( other);
    };

    /*  Move assignment operator*/
    Base& operator=(Base&& other){
        m_subBases = std::move(other.m_subBases);
        return *this;
    };

    /*  Copy assignment operator */
    Base& operator=(const Base& other){
        for(int i = 0; i < other.m_subBases.size(); i++)
            m_subBases.push_back(other.m_subBases[i]->clone());

        return *this;
    };

    /* virtual dtor */
    virtual ~Base(){
        m_subBases.clear();
    };

    /* Used for creating clones of unique_ptrs */
    virtual std::unique_ptr <Base> clone() const= 0;

    /* Do something */
    virtual void execute(float f) = 0;

    //Omitted data member access methods

protected:
    std::vector < std::unique_ptr <Base> > m_subBases;
};

class Derived1 : public Base{

public:
    Derived1() :  Base(){};

    /*  copy ctor */
    Derived1(const Derived1& other) : Base(other){
        *this = other;
    };

    /*  move ctor */
    Derived1(Derived1&& other) : Base(std::move(other)){
        *this = std::move(other);
    };

    /*  Move assignment operator*/
    Derived1& operator=(Derived1&& other){

        //This is redundant when called in the move ctor because
        // of the call to Base(std::move(other))
        m_subBases = std::move(other.m_subBases);

        m_string = other.m_string;
        return *this;
    };

    /*  Copy assignment operator */
    Derived1& operator=( const Derived1& other){

        //This is redundant when called in the copy ctor because
        // of the call to Base(other)
        for(int i = 0; i < other.m_subBases.size(); i++)
            m_subBases.push_back(other.m_subBases[i]->clone());

        m_string = other.m_string;
        return *this;
    };

    /* virtual dtor */
    virtual ~Derived1(){};

    /* Used for creating clones of unique_ptrs */
    virtual std::unique_ptr <Base> clone() const{
        return std::unique_ptr <Base> (new Derived1(*this));
    };

    virtual void execute(float f){
        std::cout << "Derived1 " << f << std::endl; 
    };
protected:

    std::string m_string;
};
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T14:27:57+00:00Added an answer on June 11, 2026 at 2:27 pm

    I’d like to offer an alternative approach. Not the Scary Rule of Five, but the Pleasant Rule of Zero, as @Tony The Lion has already suggested. A full implementation of my proposal has been coded by se­ve­ral people, and there’s a fine version in @R. Martinho Fernandes’s library, but I’ll present a simplified version.

    First, let’s recap:

    The Rule of Zero: Don’t write a copy- or move-constructor, a copy- or move-assignment ope­ra­tor, or a destructor. Instead, compose your class of components which handle a single responsibility and encap­su­late the desired behaviour for the individual resource in question.

    There’s an obvious caveat: When you design the single-responsibility class, you must of course obey:

    The Rule of Five: If you write any one of copy- or move-constructor, copy- or move-assignment ope­ra­tor, or destructor, you must implement all five. (But the “five” functions needed by this rule are actually: Destructor, Copy-Const, Move-Const, Assignment and Swap.)

    Let’s do it. First, your consumer:

    struct X;
    
    struct Base
    {
        std::vector<value_ptr<X>> v;
    };
    
    struct Derived : Base
    {
    };
    

    Note that both Base and Derived obey the Rule of Zero!

    All we need to do is implement value_ptr. If the pointee is non-polymorphic, the following will do:

    template <typename T>
    class value_ptr
    {
        T * ptr;
    public:
        // Constructors
        constexpr value_ptr()      noexcept : ptr(nullptr) { }
        constexpr value_ptr(T * p) noexcept : ptr(p)       { }
    
        // Rule of Five begins here:
        ~value_ptr() { ::delete ptr; }
        value_ptr(value_ptr const & rhs) : ptr(rhs.ptr ? ::new T(*rhs.ptr) : nullptr) { }
        value_ptr(value_ptr && rhs) noexcept : ptr(rhs.ptr) { rhs.ptr = nullptr; }
        value_ptr & operator=(value_ptr rhs) { swap(rhs); return *this; }
        void swap(value_ptr & rhs) noexcept { std::swap(rhs.ptr, ptr); }
    
        // Pointer stuff
        T & operator*() const noexcept { return *ptr; }
        T * operator->() const noexcept { return ptr; }
    };
    
    template <typename T, typename ...Args>
    value_ptr<T> make_value(Args &&... args)
    {
        return value_ptr<T>(::new T(std::forward<Args>(args)...));
    }
    

    If you would like smart pointer that handles polymorphic base class pointers, I suggest you demand that your base class provide a virtual clone() function, and that you implement a clone_ptr<T>, whose copy constructor would be like this:

    clone_ptr(clone_ptr const & rhs) : ptr(rhs.ptr ? rhs.ptr->clone() : nullptr) { }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am getting the error Cannot resolve TargetName grdGeneral . What I am trying
Im trying to resolve an issue where when using NHibernate with a SqlServerCeDriver that
I am trying to resolve a TimeSpan using Unity . Executing the container Resolve
I am trying to resolve Fatal Error in MPI_Irecv: Aborting Job and received mixed
I'm trying to resolve a problem where SGEN is throwing an error when invoked
I have a SQL Server error I'm trying to resolve. Could someone please help
I have been having the hardest time trying to resolve the weirdest error when
I got a somewhat strange error when trying to resolve the CommonDocuments directory. It
I am new to WPF and I am trying to resolve an error. I
I'm trying to resolve an IEnumerable of my dependencies through Autofac, but I need

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.