前言
细数C++编程思想的数据关系
一、Has-a
事物之间具有显然的包含关系,使用”Has a“关系,Has a关系有两种,聚合(aggragation)以及组合(composition)
composition 当整体不存在时,整体的组成部分也应当被销毁
aggragation 当整体不存在时,整体的组成部分可以继续存在
如下图示:
Unitversity 不存在的时候,部门就应当销毁(调用析构函数)
Department 不存在的时候,教师与教授仍然存在(不调用析构函数)

二、IS-a
inheritance /Generalization
猫是动物,“cat is an animal”, 是isa 的关系:等价于C++中的继承

#include <iostream>
using namespace std;
class Animal
{
public:
virtual int makeSound() {
cout << "Animal is making sound" << endl;
return 1;
}
private:
int ntimes;
};
class Cat : public Animal
{
public:
int makeSound() {
cout << "a cat is making sound" << endl;
return 1;
}
};
int main()
{
Cat *cat = new Cat();
cat->makeSound();
return 0;
}
三、Association
两个事物不具备包含关系,但具备关联关系时,使用"Association",比如医生和病人间的关系/直接关联关系

#include <cstdint>
#include <functional> // reference_wrapper
#include <iostream>
#include <string>
#include <vector>
// Since Doctor and Patient have a circular dependency, we're going to forward declare Patient
class Patient;
class Doctor
{
private:
std::string m_name{};
std::vector<std::reference_wrapper<const Patient>> m_patient{};
public:
Doctor(const std::string& name) :
m_name{ name }
{
}
void addPatient(Patient& patient);
// We'll implement this function below Patient since we need Patient to be defined at that point
friend std::ostream& operator<<(std::ostream &out, const Doctor &doctor);
const std::string& getName() const { return m_name; }
};
class Patient
{
private:
std::string m_name{};
std::vector<std::reference_wrapper<const Doctor>> m_doctor{}; // so that we can use it here
// We're going to make addDoctor private because we don't want the public to use it.
// They should use Doctor::addPatient() instead, which is publicly exposed
void addDoctor(const Doctor& doctor)
{
m_doctor.push_back(doctor);
}
public:
Patient(const std::string& name)
: m_name{ name }
{
}
// We'll implement this function below Doctor since we need Doctor to be defined at that point
friend std::ostream& operator<<(std::ostream &out, const Patient &patient);
const std::string& getName() const { return m_name; }
// We'll friend Doctor::addPatient() so it can access the private function Patient::addDoctor()
friend void Doctor::addPatient(Patient& patient);
};
void Doctor::addPatient(Patient& patient)
{
// Our doctor will add this patient
m_patient.push_back(patient);
// and the patient will also add this doctor
patient.addDoctor(*this);
}
std::ostream& operator<<(std::ostream &out, const Doctor &doctor)
{
if (doctor.m_patient.empty())
{
out << doctor.m_name << " has no patients right now";
return out;
}
out << doctor.m_name << " is seeing patients: ";
for (const auto& patient : doctor.m_patient)
out << patient.get().getName() << ' ';
return out;
}
std::ostream& operator<<(std::ostream &out, const Patient &patient)
{
if (patient.m_doctor.empty())
{
out << patient.getName() << " has no doctors right now";
return out;
}
out << patient.m_name << " is seeing doctors: ";
for (const auto& doctor : patient.m_doctor)
out << doctor.get().getName() << ' ';
return out;
}
int main()
{
// Create a Patient outside the scope of the Doctor
Patient dave{ "Dave" };
Patient frank{ "Frank" };
Patient betsy{ "Betsy" };
Doctor james{ "James" };
Doctor scott{ "Scott" };
james.addPatient(dave);
scott.addPatient(dave);
scott.addPatient(betsy);
std::cout << james << '\n';
std::cout << scott << '\n';
std::cout << dave << '\n';
std::cout << frank << '\n';
std::cout << betsy << '\n';
return 0;
}
813

被折叠的 条评论
为什么被折叠?



