Q:

Класс должен порождать дружественные классы

Представим, что я создал класс "квадрат". От него породил очень много классов разноцветных квадратов, например: жёлтый, красный, синий и т.д. Теперь я хочу сделать так, что бы цветной квадрат мог порождать при определённых обстоятельствах другие цветные квадраты. Например, жёлтый квадрат с вероятностью 30% порождает 2 красных квадрата и 1 зелёный, с вероятностью 50% 1 синий и 1 жёлтый, и так далее. Каждый цвет имеет свой набор распадов на другие цвета (хотя есть цвета, которые ничего не порождают после себя). Не знаю как это осуществить правильно. Пробовал вот как:
class квадрат{

   ....

   ....

   protected:

   ....

   std::vector(std::vector(квадрат *)) Decay;

   ....

   public:

   virtual void Initialize();

   ....

};

Теперь порождаю от него новый класс и в нем определяю функцию Initialize(), в которой описываю какие квадраты после себя оставляет данный, которую просто потом буду вызывать в конструкторах.
class жёлтый : public квадрат{

   ...

   void Initialize();

};

И описываю эту функцию:
void жёлтый::Initialize() {

    ....

    ....

    //(30%)

    Decay[0][0] = new красный;

    Decay[0][1] = new красный;

    Decay[0][2] = new зелёный;

    //(50%)

    Decay[1][0] = new синий;

    Decay[1][1] = new жёлтый;

    и т.д.

}

Как я и думал, при создании жёлтого квадрата, он внутри себя создаёт всё, что описано в векторе, включая самого себя и происходит переполнение памяти.
Я хотел создать просто вектор, в котором будут храниться указатели на объекты, а не сами объекты, а потом с определённой вероятностью объект порождал бы другие.
Подскажите пожалуйста как это сделать. На самом деле у меня задача не с квадратиками, а с распадом элементарных частиц. Каждая частица с определённой вероятностью может распасться на какой-то спектр частиц, но принцип аналогичен.
Извиняюсь, если что, я на форуме первый раз. Для меня форматирование текста осталось загадкой.

A:

Я бы предложил вот что.
Вы не храните квадраты в квадрате, а лишь функции, которые могут их создать. Эти функции, понятно, места не занимают. У вас же каждый квадрат хранит в себе другие квадраты, которые в свою очередь хранят другие квадраты. Для каждого из них вызывается функция Initialize(), создающая новые квадраты, и т. д. Поэтому избавимся от хранения квадратов, и будем держать лишь функции, которые эти квадраты создают.
Объявим их:
class square; // предварительное объявление
typedef std::function<square*()> square_creator;

Теперь сам класс квадрата. Нам нужна таблица распада, с создающими функциями и их вероятностями. Поскольку у каждого из подклассов таблица своя, функцию объявим абстрактной и виртуальной. На основе функции можно выполнять распад, его код общий для всех подклассов:
class square
{
protected:
    virtual std::vector<std::pair<square_creator, double>>& get_decay_table() = 0;

public:
    square* decay();
};

Теперь конкретные подклассы. Здесь нужно объявить таблицу распада, и возвращать её в виртуальной функции:
class yellow : public square
{
    static std::vector<std::pair<square_creator, double>> decay_table;
protected:
    virtual std::vector<std::pair<square_creator, double>>& get_decay_table()
    {
        return decay_table;
    }
};

Другой класс будет выглядеть точно так же:
class red : public square
{
    static std::vector<std::pair<square_creator, double>> decay_table;
protected:
    virtual std::vector<std::pair<square_creator, double>>& get_decay_table()
    {
        return decay_table;
    };
};

Ну и отдельно объявляем статические таблицы распада:
std::vector<std::pair<square_creator, double>> yellow::decay_table
{
    { []() { return new yellow(); }, 0.3 },
    { []() { return new red(); }, 0.7 },
};

std::vector<std::pair<square_creator, double>> red::decay_table
{
    { []() { return new yellow(); }, 0.6 },
    { []() { return new red(); }, 0.4 },
};

Для реализации decay нам необходим генератор случайных чисел. Чтобы не было повторений, сделаем его общим. Для этого добавим в square
private:
    static std::random_device rd;
    static std::mt19937 gen;
    static std::uniform_real_distribution<> dis;

и в .cpp инициализацию:
std::random_device square::rd;
std::mt19937 square::gen(square::rd());
std::uniform_real_distribution<> square::dis(0, 1);

Теперь можно реализовать функцию decay:
square* square::decay()
{
    auto& table = get_decay_table();
    double random = dis(gen);
    for (auto& entry : table)
    {
        auto probability = entry.second;
        if (random < probability)
            return entry.first();
        random -= probability;
    }
    // shouldn't happen
    return nullptr;
}

Для того, чтобы как-то отличать наши квадраты, добавим виртуальную функцию с именем в них. Теперь можно запускать тест:
int main(int argc, char *argv[])
{
    square* s = new yellow();
    for (int i = 0; i < 10; i++)
    {
        s = s->decay(); // здесь утечка памяти, не забудьте уничтожить старый квадрат!
        std::cout << s->name() << std::endl;
    }
}

Результат пробного запуска:
red
yellow
red
red
yellow
red
yellow
red
red
yellow

На всякий случай, полный код:
// эта строчка только для Visual Studio
#include "stdafx.h"

#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <random>

class square;

typedef std::function<square*()> square_creator;

class square
{
protected:
    virtual std::vector<std::pair<square_creator, double>>& get_decay_table() = 0;

private:
    static std::random_device rd;
    static std::mt19937 gen;
    static std::uniform_real_distribution<> dis;

public:
    square* decay();
    virtual std::string name() = 0;
};

std::random_device square::rd;
std::mt19937 square::gen(square::rd());
std::uniform_real_distribution<> square::dis(0, 1);

square* square::decay()
{
    auto& table = get_decay_table();
    double random = dis(gen);
    for (auto& entry : table)
    {
        auto probability = entry.second;
        if (random < probability)
            return entry.first();
        random -= probability;
    }
    // shouldn't happen
    return nullptr;
}

class yellow : public square
{
    static std::vector<std::pair<square_creator, double>> decay_table;
protected:
    virtual std::vector<std::pair<square_creator, double>>& get_decay_table()
    {
        return decay_table;
    };
public:
    virtual std::string name() { return "yellow"; };
};

class red : public square
{
    static std::vector<std::pair<square_creator, double>> decay_table;
protected:
    virtual std::vector<std::pair<square_creator, double>>& get_decay_table()
    {
        return decay_table;
    };
public:
    virtual std::string name() { return "red"; };
};

std::vector<std::pair<square_creator, double>> yellow::decay_table
{
    { []() { return new yellow(); }, 0.3 },
    { []() { return new red(); }, 0.7 },
};

std::vector<std::pair<square_creator, double>> red::decay_table
{
    { []() { return new yellow(); }, 0.6 },
    { []() { return new red(); }, 0.4 },
};

int main(int argc, char *argv[])
{
    square* s = new yellow();
    for (int i = 0; i < 10; i++)
    {
        s = s->decay(); // здесь утечка памяти, не забудьте уничтожить старый квадрат!
        std::cout << s->name() << std::endl;
    }
}

P.S.: Если у вас квадрат распадается на несколько квадратов, то вам нужно возвращать в decay std::vector<square*>, ну и соответственно в таблице держать функции создания нескольких квадратов для каждой из вероятностей.

