Работая с несколькими ОО-языками, я усвоил несколько вещей, которые помогают программировать на C ++. И это относится к вашему вопросу.
Это длинный, скучный вопрос, но, возможно, оно того стоит.
Конкретные классы, сначала
Обычно я начинаю с конкретных классов, и когда несколько классов имеют общие черты, такие как методы или поля, я создаю общий суперкласс.Многие разработчики (на любом языке), похоже, сразу переходят к созданию суперклассов, а затем к дочерним конкретным классам.
Проектирование ОО-программ может показаться, что суперклассы, будь то абстрактные или нет, там, где они спроектированы первыми.Но в реальном мире большинство классов начинаются как конкретные, а суперклассы - позже.Даже если в дизайне сначала появляются суперклассы UML или кода.
Итак, этот пример, включая данные и методы:
// ....
#include <iostream>
class Employee {
public:
Employee(); // constructor;
void SayHello();
void Work();
};
class Student {
public:
Student(); // constructor;
void SayHello();
void Study();
};
// ....
Становится так:
// ....
#include <iostream>
class Person {
public:
Person(); // constructor;
virtual void SayHello() = 0;
};
class Employee {
public:
Employee(); // constructor;
virtual void SayHello();
void Work();
};
class Student {
public:
Student(); // constructor;
virtual void SayHello();
void Study();
};
// ....
В этом предыдущем примере показаны только методы, а не данные, но применяется тот же принцип.
Избегайте закрытых полей или методов
Что-то, что я обычно делаю, чтобы избежать "частных" разделов.Если мне нужно спрятаться, я вместо этого использую «защищенный».
Итак, это:
// ....
#include <iostream>
#include <cstring>
class Person {
private:
char[512] Name;
public:
Person(); // constructor;
virtual void SayHello() = 0;
};
// ....
Становится так:
// ....
#include <iostream>
#include <cstring>
class Person {
protected:
char[512] Name;
public:
Person(); // constructor;
char[512] Name;
virtual void SayHello() = 0;
};
// ....
Если вы работаете с классом, абстрактным или нет, вы можете подумать, что вы или другие разработчики можете кодировать подкласс и обращаться к полям или методам родительского класса.
Используйте свойства (с методами accesor) вместо простых полей данных
Что меня действительно беспокоит, так это отсутствие «реальных свойств» в «C ++» и «Java».
Один из способов доступа, изменения, управления или обновления данных из объекта, его свойств, то есть полей, принимаемых с использованием методов, называемых accesors.
Свойства могут быть реализованы в C ++, используяшаблоны или просто методы кодирования от руки.
Итак, пример прямого неизолированного поля:
// ....
#include <iostream>
#include <cstring>
class Person {
public:
Person(); // constructor;
char[512] Name;
virtual void SayHello() = 0;
};
int main (...) {
Person thisPerson = new Person();
strcpy(thisPerson.Name, "John Doe");
cout << thisPerson.Name << "\n";
delete thisPerson;
}
// ....
Становится примером изолированного свойства:
// ....
#include <iostream>
#include <cstring>
class Person {
protected:
// isolated data field
char[512] Name;
public:
Person(); // constructor;
virtual void SayHello() = 0;
// public data field accesor reader method or "getter"
const char* getName();
// public data field accesor writer method or "setter"
void setName(const char* AName);
};
const char Person::getName() {
char char* Result = this.FName;
return Result;
}
void setName(const char* AName) {
bool IsValid = false;
// do some validation before actually modifing field
// ...
if (IsValid)
{
strcpy(this.FName, AName);
}
}
int main (...) {
Person thisPerson = new Person();
// should be read as "thisPerson.Name = "John Doe";"
thisPerson.setName("John Doe");
// should be read as "cout << thisPerson.Name;"
cout << thisPerson.getName() << "\n";
delete thisPerson;
}
// ....
Многие разработчики на C ++ не любят "свойства" из-за отсутствияконтроля.Я думаю, что вы должны использовать для доступа к данным в качестве вашего вопроса, но, как и любая функция, должны быть «правильно использованы».
Свойства методов доступа должны быть виртуальными
В некоторыхВ языках можно реализовать концепцию свойств, напрямую обращаясь к полю данных объекта, читая и записывая методы или смешивая оба подхода.Чтобы сделать вещи более сложными, методы могут быть «виртуальными» или «не виртуальными».
Когда я использую свойства, я всегда использую виртуальные методы для доступа к ним.Есть скорость в памяти и скорости, но это того стоит.Свойства с виртуальными переопределенными методами позволяют контролировать и получать доступ к данным объектов.
Сводка
Ваш вопрос касается того, как реализовать данные, как изолировать данные и как получить доступданные в классе и как реализовать такие функции в дочерних классах.
Я читал аналогичные вопросы в Stackoverflow, но я пришел к выводу, что некоторые вопросы связаны с отсутствием «реальных свойств» вC ++.
Возможно, вы захотите управлять доступом к данным и их изоляции с помощью «свойств».
И, возможно, захотите попытаться изучить другие ОО, где понятие «свойства»он реализован, например: VB (.NET), C #, Delphi, D или Vala.
И позже, при необходимости, попытайтесь реализовать эту концепцию в своих программах на C ++.У меня есть класс в C ++, в котором есть простые поля данных, поля, которые обрабатываются как «свойства», как в Java, с методами accesor, или смешивают оба, когда это необходимо.
Это не означает, что вы переписываете приложение, над которым работаетеили пытаетесь выяснить, какой язык программирования лучше, просто изучите что-то на других языках программирования, которые могут помочь вашей работе.