Показать сообщение отдельно
Старый 18.12.2010, 04:21   #22
Samodelkin
Мастер
 
Регистрация: 12.01.2009
Сообщений: 979
Написано 388 полезных сообщений
(для 631 пользователей)
Ответ: Undefined reference to...

Можно сделать вот так:
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;
}
Насчет ошибки из первого поста вероятней всего компоновщику не указан объектный файл с методами класса.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Samodelkin за это полезное сообщение:
pax (18.12.2010), Reizel (18.12.2010)