с++ и виртуальное наследование

283
14 июля 2018, 08:30

Необходимо создать базовый класс который будет иметь 4 наследника. Вся проблема в том, что мне нужен базовый класс в одном экземпляре, так как там будут храниться указатели на наследуемые объекты + есть наследуемые классы которые не будут создаваться сразу и мне надо определять какие будут созданы а какие нет по массиву.

Вопрос заключается в следующем: Есть код:

header
class dataBase
{
public:
std::vector<dataBase*> data;
dataBase();
int a=0;
static int sl;
};
class type1 :  public virtual dataBase
{
public:
type1();
int b;
};
class type2:  public virtual dataBase
{
public:
type2();
int c;
};

где в реализации для каждого:

int dataBase::sl=0;
dataBase::dataBase()
{
sl++;
a=sl;
}
type1::type1(){
data.insert(data.end(), this);
b=a;
}
type2::type2()
{
data.insert(data.end(), this);
c=a;
}

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

А если в переменную а записать с наследуемого класса type1, то в type2 при изъятии получил другое число (random, это если отбросить код конструктора.)

Прошу, помогите разобраться. Спасибо за ранее.

Answer 1

как я понял это дает возможность не создавать копию базового класса, все равно создает копию

Он гарантирует, что среди всех предков данного класса, любой предок будет создан только один в иерархии для данного класса.
У вас же каждый type1 и type2 имеет по ОДНОМУ уникальному предку, у каждого класса эти предки уникальны, соответственно, каждый предок будет создан для каждого класса потомка. Поэтому у вас здесь virtual не играет никакой роли.
virtual может имеет значение только при множественном наследовании, когда у класса будет несколько предков, и мы хотим, чтобы в иерархии наследования не было копий предков.

Пример:

class A {  };
class B: public A {};
class C: public A {};
class D: public B, public C {};  

В иерархии класса D имеются следующие потомки: B, A, C, A
Сделав вот так

class A {  };
class B: public virtual A {};
class C: public virtual  A {};
class D: public B, public C {};  

мы говорим, что нам в иерархии класса D необходимо иметь только один потомок А, соответственно вместо создания 2 экземпляров класса А, будет создан ТОЛЬКО ОДИН ЕДНИСТВЕННЫЙ: A, B, C

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

READ ALSO
MemoryPuzzle — простая игра в консоли [требует правки]

MemoryPuzzle — простая игра в консоли [требует правки]

Я тут сделал свою первую нормальную консольную игру на С++Это простая игра

184
Как работает sync?

Как работает sync?

Не могу понять как он работаетЕсть пример:

187
Потомок от std::set с лямбда функцией сравнения

Потомок от std::set с лямбда функцией сравнения

Подскажите где прописать код лямбда функции сравнения, например, такой:

197
Трёхмерный массив с пропусками (C++, map)

Трёхмерный массив с пропусками (C++, map)

У меня есть трёхмерный массив с вот таким объявлением:

240