Spec-Zone.ru › GCC 6

13.7.4 Неявное присваивание копирования для виртуальных базовых классов

Когда базовый класс является виртуальным, только один подобъект базового класса принадлежит каждому полному объекту. Кроме того, конструкторы и деструкторы вызываются только один раз и вызываются из класса, производного от самого производного класса. Однако поведение таких объектов при присваивании не определено. Например:

struct Base{
  char *name;
  Base(char *n) : name(strdup(n)){}
  Base& operator= (const Base& other){
   free (name);
   name = strdup (other.name);
  }
};

struct A:virtual Base{
  int val;
  A():Base("A"){}
};

struct B:virtual Base{
  int bval;
  B():Base("B"){}
};

struct Derived:public A, public B{
  Derived():Base("Derived"){}
};

void func(Derived &d1, Derived &d2)
{
  d1 = d2;
}

Стандарт C++ определяет, что «Base::Base» вызывается только один раз при построении или копирующем построении объекта Derived. Не определено, вызывается ли «Base::operator=» более одного раза при вызове неявного присваивания копирования для объектов Derived (как это происходит внутри «func» в примере).

G++ реализует «интуитивный» алгоритм для присваивания копирования: присвоить все прямые базовые классы, затем присвоить все члены. В этом алгоритме подобъект виртуального базового класса может встречаться более одного раза. В примере копирование происходит в следующем порядке: «val», «name» (через strdup), «bval», и «name» снова.

Если код приложения полагается на присваивание копирования, оператор пользовательского присваивания копирования устраняет любые неопределенности. С таким оператором приложение может определить, как и нужно ли присваивать подобъект виртуального базового класса.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.5.0/gcc/Copy-Assignment.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API