Глубокое копирование константного указателя на константный объект - PullRequest
0 голосов
/ 09 декабря 2011

У меня есть конструктор объекта, который принимает константный указатель на константный объект

A::A( const B* const ex): m_B(B){};

где m_B:

const B* const m_B;

Я сейчас пытаюсь создать конструктор копирования и оператор присваивания. Я безуспешно пробовал следующее.

Конструктор копирования:

A::A( const A& cpy): *m_B(*cpy.m_B) {}

Это не работает ... как мне подойти к этому? Оператор присваивания:

A& A::operator=(const A& rhs) {

 *m_B = *rhs.m_B // I know this won't work because const cannot be assigned 
                 // error: assignment of read-only data-member
}

Есть идеи, как решить эту проблему?

Ответы [ 4 ]

2 голосов
/ 09 декабря 2011

Если вам все равно нужны глубокие копии, зачем вам указатель? Просто есть необработанный объект.

class B{
  // ...
};

class A{
  const B _b;
public:
  A(A const& other)
    : _b(other._b) {}

private:
  // no assignment operator, since const objects can't be reassigned
  A& operator=(A const&); // undefined
};
0 голосов
/ 30 сентября 2015

Оператор «размещение нового» может быть полезен при назначении объектов, имеющих указатели констант.

class ref
{
public:
  // Normal constructor creates new immutable reference.
  ref(const char* const ptr, size_t len): m_ptr(ptr),m_len(len) {}
  // Copy constructor creates new copy of existing immutable reference.
  ref(const ref& o): m_ptr(o.m_ptr),m_len(o.m_len) {}
  // Assignment operator replaces existing immutable reference with another one.
  // Previous reference is gone.
  ref& operator=(const ref& o) { new (this) ref(o.m_ptr, o.m_len); return *this; }
private:
  const char* const m_ptr;
  size_t m_len;
}
0 голосов
/ 09 декабря 2011

Оператору присваивания может потребоваться создать новый экземпляр с new:

A& A::operator=(const A& rhs) {
    m_B = new B(rhs.m_B);
    return *this;
}

Конечно, вы должны следить за этим, чтобы вы могли delete указатель, если вы выделите его. Если вы не хотите отслеживать, также используйте new в конструкторе.

Или, что еще лучше, используйте новый shared_ptr, чтобы вообще не заботиться о указателях.

0 голосов
/ 09 декабря 2011

Ваша проблема в том, что конструкторы не имеют возвращаемого значения.

И оператор присваивания operator=, а не operator().

В вашем конструкторе вы взяли указатель и сохранили указатель, а не содержимое объекта, на который указывает указатель. Если вы используете эту семантику, вам следует копировать только указатели, а не копировать содержимое: (или у вас есть что-то еще, чего можно достичь?)

class B;

class A {
public:
    const B* m_b;
    A( const B* const ex): m_B(ex){};

    //copy constructor
    A(const A& cpy): m_B(cpy.m_B){};
    //assignment operator
    A& operator=(const A&cpy) {m_B = cpy.m_B;};
};
...