Можно сделать вот так:
class.hpp
#ifndef __CLASS_H__
#define __CLASS_H__
#include <stdio.h>
#include <iostream>
// Абстрактный базовый класс животного
class Animal {
protected:
short maxHealth; // Максимальное количество HP
public:
Animal(short h); // Конструктор класса в который можно передавать количество HP
virtual Animal* Create() = 0; // Интерфейс для доступа к виртуальным методам суперклассов
// Статическая функция с шаблоном вида животного.
// Статическая для того чтобы ее можно было вызывать даже когда нету ни одного объекта и чтобы соблюдать правила инкапсуляции
// Статические методы могут работать только со статическими данными класса.
template<typename T> static Animal* CreateAnimal(short h) {
std::cout << "Animal::Create" << std::endl;
population++; // Увеличиваем популяцию на один
return new T(h);
}
static int population; // Статическая переменная - сущетсвует вне объектов, фиксирует общее количество животных
};
// Класс животного КАБАН
class WildBoar : public Animal {
public:
WildBoar(short h);
virtual Animal* Create(); // Может производить сородичей
};
// Клас животного ВОЛК
class Wolf : public Animal {
public:
Wolf(short h);
virtual Animal* Create(); // Также может производить сородичей
};
#endif
class.cpp
#include "class.h"
// Конструктор класса Animal вызывается в конструкторах других реальных классов
Animal::Animal(short h) :
maxHealth(h)
{ };
WildBoar::WildBoar(short h) :
Animal(h) // Вот тут вызываем конструктор базового класса
{ }
Animal* WildBoar::Create() {
std::cout << "WildBoar::Create" << std::endl;
CreateAnimal<WildBoar>(100); // Передаем тип вместе с количеством HP
}
Wolf::Wolf(short h) :
Animal(h)
{ }
Animal* Wolf::Create() {
std::cout << "Wolf::Create" << std::endl;
CreateAnimal<Wolf>(50);
}
main.cpp
#include "class.h"
// population статическая переменная а значит она уже создана.
// Нужно указать компилятору что она в другой единице трансляции чтобы ее использовать тут.
extern int Animal::population;
int main() {
// Инициализируем
Animal::population = 0;
// Тут еще 0
std::cout << Animal::population << std::endl;
// Можно создать указатели на любого животного и создать их через статическую функцию
Animal* wb = Animal::CreateAnimal<WildBoar>(100);
Animal* wf = Animal::CreateAnimal<Wolf>(50);
// Теперь их двое
std::cout << Animal::population << std::endl;
// Животные могут сами себя производить - каждый свой тип (если не указано иное в методах Create)
wb->Create();
wf->Create();
// Теперь их четверо
std::cout << Animal::population << std::endl;
return 0;
}
Насчет ошибки из первого поста вероятней всего компоновщику не указан объектный файл с методами класса.