Nie ma odgórnych ustaleń, poza dedykowaną rolą - konstruktor powinien niejako przygotować obiekt do użytku, tak aby zaraz po jego utworzeniu dało się z niego korzystać. Raczej należy unikać sytuacji, jeśli tylko oczywiście możemy, że najpierw obiekt trzeba utworzyć, potem musieć robić na nim jakieś obiekt.init1(), obiekt.init2() (a już Swarogu broń w określonej kolejności) bo inaczej nie będzie zachowywał się poprawnie.
Czy wykorzystywać wewnątrz niego jakieś metody, też nie ma na to reguły, zależy od kontekstu. Ot przykład konstruktora z jednej z moich klas:
(@Marooned @Adam Boduch - Panowie, a gdzie znacznik spoiler/spoiler/?)
WeaponsDatabase& WeaponsDatabase::getInstance()
{
static WeaponsDatabase instance;
return instance;
}
WeaponsDatabase::WeaponsDatabase()
{
QVector<QString> weaponFilesToExclude = DatabasesManager::getInstance().getFilesToExclude("WeaponsDatabase");
QDir weaponsDir(DatabasesManager::getInstance().getJsonDataPath() + "/weapon", "*.json", QDir::Name|QDir::IgnoreCase, QDir::Files);
QStringList weaponsFiles = weaponsDir.entryList();
foreach (const QString &weaponFile, weaponsFiles)
{
if (weaponFilesToExclude.contains(weaponFile))
{
continue;
}
QFile file(weaponsDir.absolutePath() + '/' + weaponFile);
if (file.open(QFile::ReadOnly))
{
//get json object for a weapon
QJsonObject json = QJsonDocument::fromJson(file.readAll()).object();
file.close();
//the weapon does not exist yet, so it must be built and added to map of WeaponData
WeaponData *weapon = new WeaponData;
weapon->slotSize = json.value("InventorySize").toInt();
weapon->tonnage = json.value("Tonnage").toInt();
weapon->heat = json.value("HeatGenerated").toInt();
weapon->damage = json.value("Damage").toInt();
weapon->stabilityDamage = json.value("Instability").toInt();
weapon->heatDamage = json.value("HeatDamage").toInt();
weapon->startingAmmoCapacity = json.value("StartingAmmoCapacity").toInt();
weapon->ammoCategory = json.value("AmmoCategory").toString();
weapon->type = json.value("ComponentType").toString();
weapon->subType = json.value("WeaponSubType").toString();
weapon->bonusValueA = json.value("BonusValueA").toString();
weapon->bonusValueB = json.value("BonusValueB").toString();
weapon->name = json.value("Description").toObject().value("UIName").toString();
QString hardpoint = json.value("Category").toString();
SettingsContainer &settings = SettingsContainer::getInstance();
if (hardpoint == "Ballistic")
{
weapon->hardpoint = HardpointTypes::Ballistic;
weapon->color = settings.getColorForEquipment(HardpointTypes::Ballistic);
}
else if (hardpoint == "Energy")
{
weapon->hardpoint = HardpointTypes::Energy;
weapon->color = settings.getColorForEquipment(HardpointTypes::Energy);
}
else if (hardpoint == "Missile")
{
weapon->hardpoint = HardpointTypes::Missile;
weapon->color = settings.getColorForEquipment(HardpointTypes::Missile);
}
else//the only possible hardpoint type left is support/antipersonnel
{
weapon->hardpoint = HardpointTypes::Antipersonnel;
weapon->color = settings.getColorForEquipment(HardpointTypes::Antipersonnel);
}
//for now all weapons can be put anywhere where they fit.In the future however there should be added more conditions after the "All" check
QString allowedLocations = json.value("AllowedLocations").toString();
if (allowedLocations == "All")
{
weapon->allowedLocations = static_cast<MechLocations::Location>(weapon->allowedLocations | MechLocations::All);
}
//store the weapon in a map with same QString ID as it is in .JSON
QString componentDefID(weaponFile);
componentDefID.chop(5);//get rid of .json from the end
weapons.insert(componentDefID, weapon);
}
}
}
Z kolei konstruktor bardzo podobnej klasy wygląda tak:
EquipmentDatabase &EquipmentDatabase::getInstance()
{
static EquipmentDatabase instance;
return instance;
}
EquipmentDatabase::EquipmentDatabase()
{
createEquipmentMap("AmmunitionBoxDatabase", "/ammunitionBox", Categories::ammo, true);
createEquipmentMap("JumpJetsDatabase", "/jumpjets", Categories::jumpJets);
createEquipmentMap("HeatsinksDatabase", "/heatsinks", Categories::heatsinks);
createEquipmentMap("ActuatorsDatabase", "/upgrades/actuators", Categories::actuators);
createEquipmentMap("CockpitModsDatabase", "/upgrades/cockpitMods", Categories::cockpitMods);
createEquipmentMap("GyrosDatabase", "/upgrades/gyros", Categories::gyros);
createEquipmentMap("TargetingTrackingDatabase", "/upgrades/targetTrackingSystem", Categories::computers);
}
void EquipmentDatabase::createEquipmentMap(const QString &exclusionsDatabaseName, const QString &equipmentDirectoryName, const QString &categoryName, bool isAmmo)
{
//robi w sumie to samo co klasa wyżej - wczytywanie danych z .json-ów i tworzenie na ich podstawie mapy
}
w tym createEquipmentMap z grubsza jest to samo, co w konstruktorze WeaponsDatabase, ale ponieważ każda z kategorii różniła się tylko niuansami takimi jak położenie folderu zawierającego .json-y z danymi to zamiast 7x powtarzać niemal identyczny kod wydzieliłem to do osobnej funkcji. Problem był z amunicją, bo ona ma inny schemat kolorystyczny - z tym poradziłem sobie wprowadzając dodatkowy parametr, domyślnie false.