ð TOP / ã¬ã¬ã·ãŒC++ L11ïŒç¬èªã¡ã¢ãªããŒã«
ã¬ã¬ã·ãŒç¬¬11ç« ïŒç¬èªã¡ã¢ãªã¢ãã±ãŒã¿ãšåºå®é·ããŒã«ç®¡ç
ã²ãŒã çŸå Žã®new/deleteçŠæ¢ä»€ïŒãã©ã°ã¡ã³ããŒã·ã§ã³æ²æ»
ãšO(1)çéåºå®é·ã¡ã¢ãªããŒã«
ã²ãŒã éçºã®çŸå Žããšãããã³ã³ã·ã¥ãŒãæ©ããªã¢ã«ã¿ã€ã ã¢ã¯ã·ã§ã³ã®çŸå Žã«ã¯ãå€ãããäŒããçµ¶å¯Ÿã®æããããŸããããã¯ãã²ãŒã ãã¬ã€ã®ã¡ã€ã³ã«ãŒãäžã«ç new ãç delete ã絶察ã«åŒãã§ã¯ãªããªãããšããçŠæ¢ä»€ã§ããOSã®æ±çšã¡ã¢ãªã¢ãã±ãŒã¿ïŒmalloc/newïŒã¯ããã€ã©ãã§ç©ºãã¡ã¢ãªãæ¢ããäºæž¬ã§ãããçªçºçãªãã¬ãŒã èœã¡ïŒã¹ãã€ã¯ïŒãåŒãèµ·ãããŸããããã«æ·±å»ãªã®ããã¡ã¢ãªã®æçåïŒãã©ã°ã¡ã³ããŒã·ã§ã³ïŒãã§ããã¡ã¢ãªã®ç©ºãç·éã¯ååã«ããã®ã«ãé£ç¶ããã¡ã¢ãªã確ä¿ã§ããã²ãŒã ã匷å¶ã¯ã©ãã·ã¥ããææã®ãã°ã§ããæ¬ç« ã§ã¯ã匟å¹ãããŒãã£ã¯ã«ãªã©ã®åçš®ãªããžã§ã¯ããäºåã«äžæ¬ç¢ºä¿ãã空ãé åèªäœããªã³ã¯ãªã¹ããšããŠåå©çšããäŒèª¬ã®ææ³ãåºå®é·ã¡ã¢ãªããŒã«ïŒFixed-Size Memory PoolïŒãã培åºè§£åãããã«C++ã®æ·±æ·µã§ããããã¬ãŒã¹ã¡ã³ãnewããšãæç€ºçãã¹ãã©ã¯ã¿åŒã³åºããããã¹ã¿ãŒããO(1)宿°æéã§çéã«ã¡ã¢ãªãåã売ãããããã¯ãªãªãã£ã®ç¬èªã¢ãã±ãŒã¿ãæ§ç¯ããŸãã
L11.1 ãªãã²ãŒã æ¬ç·šäžã® new/delete ã¯å³çŠãããã®ãïŒ
OSã·ã¹ãã ã³ãŒã«ã®ãªãŒããŒããããšãé·æé皌åã§ã²ãŒã ã確å®ã«æ»ã«è³ãããããã¡ã¢ãªãã©ã°ã¡ã³ããŒã·ã§ã³ãã®ææãè§£æããŸãã
ð§ ãã³ã®ã³å
茩
ãã³å
çâŠâŠïŒ24æéèä¹
ã®æŸçœ®ãããã°ãã¹ããããŠããããèµ·åããŠ12æéçµã£ããããã§çªç¶ std::bad_alloc ã§ã²ãŒã ãã¯ã©ãã·ã¥ããŠããŸããŸããâŠâŠïŒã¿ã¹ã¯ãããŒãžã£ã§èŠããšãã¡ã¢ãªã¯ãŸã åå以äžäœã£ãŠããã®ã«ããªããã¡ã¢ãªäžè¶³ãã«ãªããã§ããïŒïŒ
ð»ââïž ã·ãã¯ãå
ç
ãµãã£ãµãã£ãµãïŒãããããã²ãŒã ããã°ã©ããå€éãéãäžããããæªéããå€éšãã©ã°ã¡ã³ããŒã·ã§ã³ïŒã¡ã¢ãªã®æçåïŒãã®ä»æ¥ããïŒ
ð§ ãã³ã®ã³å
茩
æçåâŠâŠïŒã¡ã¢ãªã®ç©ºã容éãããã®ã«ç¢ºä¿ã§ããªãã£ãŠãã©ãããããšã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
æ¬æ£ãæ³åããŠã¿ãã1ååã®ééã100ç®æã«ãã£ãŠããåã10ååã®å
šéã¯ã©ãã«ãåãŸãã¬ãããïŒåŒŸããšãã§ã¯ããæ¯ãã¬ãŒã new ãš delete ã§ç¡ç§©åºã«åºãå
¥ãããŠãããšãã¡ã¢ãªç©ºéãè«é£ãç¶æ
ïŒã¢ã¶ã€ã¯ç¶ïŒã«ãªããé£ç¶ãã空ãé åãå
šæ»
ããŠããŸãã®ããïŒ
ð FragmentationVisualizer.cpp
#include <iostream>
#include <vector>
#include <chrono>
// 匟ãªããžã§ã¯ãïŒ48ãã€ãïŒ
struct Bullet {
float x, y;
float vx, vy;
int damage;
int lifeTimer;
char padding[24]; // ãªã¢ã«ãªãµã€ãºãã·ãã¥ã¬ãŒã
};
// â æªãäŸïŒæ¯ãã¬ãŒã ã®ããŒã確ä¿ãšã©ã³ãã ç Žæ£ïŒæçåã®åçŸïŒ
void benchmarkHeap() {
auto start = std::chrono::high_resolution_clock::now();
std::vector<Bullet*> activeBullets;
activeBullets.reserve(10000);
for (int frame = 0; frame < 10000; ++frame) {
// æ¯ãã¬ãŒã 10åçæ
for (int i = 0; i < 10; ++i) {
activeBullets.push_back(new Bullet{0, 0, 1, 1, 10, 60, {}});
}
// å€ã匟ãéäžã§éåŒãåé€ïŒè«é£ããäœãïŒ
if (activeBullets.size() > 500) {
for (int i = 0; i < 5; ++i) {
delete activeBullets[i];
}
activeBullets.erase(activeBullets.begin(), activeBullets.begin() + 5);
}
}
for (auto* b : activeBullets) delete b;
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Heap new/delete time: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
<< " ms\n";
}
L11.2 ã¡ã¢ãªæ¶è²»ãŒãã®å¥è¡ïŒåã蟌ã¿ããªãŒãªã¹ãïŒEmbedded Free ListïŒ
空ããŠããã¡ã¢ãªé åãã®ãã®ããªã³ã¯ãªã¹ãã®ã次ã®ãã€ã³ã¿ããšããŠåå©çšãããã²ãŒã ããã°ã©ãç§äŒã®ã¡ã¢ãªç¯çŽãã¯ããã¯ãç¿åŸããŸãã
ð§ ãã³ã®ã³å
茩
ããŒã«ã空ããŠããå Žæã管çããããã«ãstd::vector<int> freeIndices; ãšã bool isUsed[2048]; ã¿ãããªç®¡ççšå€æ°ãå¥éå¿
èŠãªããããªãã§ããïŒããã ãšã¡ã¢ãªãäºéã«é£ãããŠããŸããŸãããïŒ
ð»ââïž ã·ãã¯ãå
ç
ãããããã®ç骚é ãïŒã䜿ã£ãŠããªãã¹ãããã®äžã«ã次ã®ç©ºãã¹ããããžã®ãã€ã³ã¿ãçŽæ¥æžã蟌ããã®ããïŒããããåã蟌ã¿ããªãŒãªã¹ãïŒEmbedded Free ListïŒããšåŒã¶ïŒ
ð§ ãã³ã®ã³å
茩
ããã£ïŒïŒäœ¿ã£ãŠããªãã¡ã¢ãªã«ãã€ã³ã¿ãæžã蟌ãïŒïŒãããªããšããŠå
ã®ããŒã¿ãå£ãããããªããã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
䜿ã£ãŠãããïŒè²žãåºããŠããªãïŒã®ãããããäœãæžãããèªç±ãããïŒãªããžã§ã¯ããšããŠè²žãåºãç¬éã«äžæžããããè¿åŽããããåã³ãã€ã³ã¿ãæžã蟌ãã管çãªãŒããŒãããã¯ãé©ç°ã®0ãã€ããããïŒ
ð FixedMemoryPool.hpp
#pragma once
#include <cstddef>
#include <new>
#include <utility>
#include <cassert>
template <typename T, size_t Capacity>
class FixedMemoryPool {
private:
// ã¹ãããã®å
±çšäœïŒUnionïŒïŒ
// 貞åºäžã¯ T ã®çã¡ã¢ãªé åãšããŠæ©èœãã
// 空ãç¶æ
ã®æã¯æ¬¡ã®ç©ºãããŒããžã®ãã€ã³ã¿ãšããŠæ©èœããïŒ
union Slot {
alignas(alignof(T)) char storage[sizeof(T)];
Slot* next; // 空ããªã¹ãé£çµçšãã€ã³ã¿
};
Slot m_pool[Capacity]; // é£ç¶ãã巚倧ã¡ã¢ãªãããã¯
Slot* m_freeListHead; // 次ã«è²žãåºãã空ãã¹ãããã®å
é
size_t m_allocatedCount;
public:
FixedMemoryPool() : m_freeListHead(nullptr), m_allocatedCount(0) {
// å
šã¹ããããèã¥ãåŒã«ããªãŒãªã¹ããžç¹ã
for (size_t i = 0; i < Capacity - 1; ++i) {
m_pool[i].next = &m_pool[i + 1];
}
m_pool[Capacity - 1].next = nullptr;
m_freeListHead = &m_pool[0];
}
// O(1) ã§ã¡ã¢ãªãå²ãåœãŠãã³ã³ã¹ãã©ã¯ã¿ãåŒã³åºã
template <typename... Args>
T* allocate(Args&&... args) {
if (!m_freeListHead) {
return nullptr; // ããŒã«æ¯æžïŒ
}
// 1. ããªãŒãªã¹ãã®å
é ãåãåºã
Slot* slot = m_freeListHead;
m_freeListHead = m_freeListHead->next;
++m_allocatedCount;
// 2. ãã¬ãŒã¹ã¡ã³ã new ã§ãã®ã¢ãã¬ã¹äžã« T ãçŽæ¥æ§ç¯ïŒ
return new (slot->storage) T(std::forward<Args>(args)...);
}
// O(1) ã§ãã¹ãã©ã¯ã¿ãåŒã³åºããã¡ã¢ãªãããŒã«ãžè¿åŽ
void deallocate(T* ptr) {
if (!ptr) return;
// 1. æç€ºçãã¹ãã©ã¯ã¿åŒã³åºãïŒã¡ã¢ãªã¯è§£æŸããªãïŒïŒ
ptr->~T();
// 2. ã¹ããããããªãŒãªã¹ãã®å
é ãžå·®ãæ»ã
Slot* slot = reinterpret_cast<Slot*>(ptr);
slot->next = m_freeListHead;
m_freeListHead = slot;
--m_allocatedCount;
}
size_t allocatedCount() const { return m_allocatedCount; }
size_t capacity() const { return Capacity; }
bool isFull() const { return m_freeListHead == nullptr; }
};
L11.3 C++ã®æ·±æ·µïŒãã¬ãŒã¹ã¡ã³ãnewãšæç€ºçãã¹ãã©ã¯ã¿åŒã³åºã
ãã¡ã¢ãªã®å²ãåœãŠããšããªããžã§ã¯ãã®åæåããå®å
šã«åãé¢ããæšæºã©ã€ãã©ãªïŒstd::vectorçïŒã®æ ¹å¹¹ããªãè¶
çµ¶ææ³ãæ¥µããŸãã
ð§ ãã³ã®ã³å
茩
ã³ãŒãã«åºãŠãã new (slot->storage) T(...) ãš ptr->~T() ã£ãŠäœã§ããïŒïŒãã¹ãã©ã¯ã¿ãæåã§çŽæ¥åŒã³åºããŠããã®ãªããŠåããŠèŠãŸããâŠâŠïŒå£ãããããªããã§ããïŒïŒ
ð»ââïž ã·ãã¯ãå
ç
ãããC++ããã°ã©ããå¿
ãç¥ã£ãŠããã¹ãç§å¥¥çŸ©ããïŒæ®éã® new ã¯ãâ mallocã§ã¡ã¢ãªç¢ºä¿ãïŒãâ¡ã³ã³ã¹ãã©ã¯ã¿åŒã³åºããã®2ã€ãåæã«è¡ããã ãããã¬ãŒã¹ã¡ã³ã newãã¯ãæ¢ã«ç¢ºä¿æžã¿ã®ã¡ã¢ãªçªå°ãæž¡ãããâ¡ã®ã³ã³ã¹ãã©ã¯ã¿åŒã³åºãã ãããè¡ãã®ããïŒ
ð§ ãã³ã®ã³å
茩
ãªãã»ã©ïŒãããçä»ããæã¯ãªã delete ptr ãããã¡ãªãã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
ãã delete ptr ãåŒãã ããOSã®ããŒãè§£æŸé¢æ°ïŒfreeïŒãèµ°ããããŒã«å
šäœã®ã¡ã¢ãªé
åããšå¹ãé£ãã§ã¯ã©ãã·ã¥ããŠããŸãïŒã ãããâ ãã¹ãã©ã¯ã¿ã ããæç€ºçã«åŒã³åºãïŒptr->~T()ïŒããã¡ã¢ãªã¯èªåã®ããŒã«ã®ããªãŒãªã¹ãã«æ»ãã®ããïŒ
ð PlacementNewDemo.cpp
#include <iostream>
#include <new> // ãã¬ãŒã¹ã¡ã³ã new ã®ããã«å¿
é
class ExplosionParticle {
private:
int m_id;
public:
ExplosionParticle(int id) : m_id(id) {
std::cout << "Particle [" << m_id << "] èªçïŒã³ã³ã¹ãã©ã¯ã¿å®è¡ïŒ\n";
}
~ExplosionParticle() {
std::cout << "Particle [" << m_id << "] çæ£çµäºïŒãã¹ãã©ã¯ã¿å®è¡ïŒ\n";
}
void render() {
std::cout << "Particle [" << m_id << "] æç»äž...\n";
}
};
int main() {
// 1. ã¹ã¿ãã¯äžã«çã¡ã¢ãªé åãã¢ã©ã€ã¡ã³ãèæ
®ã§çšæ
alignas(ExplosionParticle) char rawMemory[sizeof(ExplosionParticle)];
std::cout << "--- 1. ãã¬ãŒã¹ã¡ã³ã new ã§çã¡ã¢ãªäžã«çŽæ¥ã€ã³ã¹ã¿ã³ã¹å ---\n";
// ã¡ã¢ãªç¢ºä¿ã¯è¡ãããrawMemory ã®äœçœ®ã«ãªããžã§ã¯ããæ§ç¯ãã
ExplosionParticle* p = new (rawMemory) ExplosionParticle(42);
p->render();
std::cout << "\n--- 2. æç€ºçãã¹ãã©ã¯ã¿åŒã³åºã ---\n";
// ã¡ã¢ãªè§£æŸã¯è¡ãããåŸçä»ãåŠçïŒãã¹ãã©ã¯ã¿ïŒã®ã¿ãå®è¡ïŒ
// â 絶察㫠delete p; ãåŒãã§ã¯ãªããªãïŒrawMemory ã¯ã¹ã¿ãã¯ãªã®ã§å³æ»ïŒ
p->~ExplosionParticle();
std::cout << "\n--- 3. åãçã¡ã¢ãªé åã«å¥ã®ãªããžã§ã¯ããåæ§ç¯ïŒ ---\n";
ExplosionParticle* p2 = new (rawMemory) ExplosionParticle(99);
p2->render();
p2->~ExplosionParticle();
return 0;
}
L11.4 å®è·µïŒã€ã³ããŒããŒã²ãŒã ã®åŒŸå¹ïŒããŒãã£ã¯ã«ããŒã«çµ±å
å®éã®ã²ãŒã ã«ãŒãã«åºå®é·ã¡ã¢ãªããŒã«ãçµã¿èŸŒã¿ã1ç§éã«æ°åçºã®åŒŸãåºçŸã»æ¶æ»
ããŠãããŒã確ä¿åæ°ãŒããç¶æããå
ç¢ãªèšèšã宿ãããŸãã
ð§ ãã³ã®ã³å
茩
å
çïŒåºå®é·ã¡ã¢ãªããŒã«ãã€ã³ããŒããŒã®åŒŸïŒBulletïŒãšæµã®ççºç«è±ïŒParticleïŒã«çµã¿èŸŒãã ãã匟å¹ããããæ¿ãããªã£ãŠããã¬ãŒã ã¬ãŒãã60FPSã«ãã¿æ¢ãŸãããããã«ãªããŸããïŒ
ð»ââïž ã·ãã¯ãå
ç
ããïŒOSãžã®ã¢ãã±ãŒã·ã§ã³èŠæ±ããŒãã«ãªããããã«ã¡ã¢ãªãé£ç¶ããŠããããCPUã®ãã£ãã·ã¥ãããçãè·³ãäžãã£ã蚌æ ãããªïŒãããåçšã²ãŒã ãšã³ãžã³ã®å¿èéšããïŒ
ð GameBulletManager.hpp
#pragma once
#include "FixedMemoryPool.hpp"
#include <vector>
#include <iostream>
struct Bullet {
float x, y;
float vy;
bool isAlive;
Bullet(float startX, float startY, float speedY)
: x(startX), y(startY), vy(speedY), isAlive(true) {}
void update() {
y += vy;
if (y < 0.0f || y > 600.0f) {
isAlive = false; // ç»é¢å€ã§æ»äº¡
}
}
};
class GameBulletManager {
private:
// æå€§1024çºã®åŒŸãäºåäžæ¬ç¢ºä¿ããããŒã«
FixedMemoryPool<Bullet, 1024> m_pool;
// ç»é¢äžã§çŸåšã¢ã¯ãã£ããªåŒŸã®ãã€ã³ã¿ãªã¹ã
std::vector<Bullet*> m_activeBullets;
public:
void spawnBullet(float x, float y, float vy) {
Bullet* b = m_pool.allocate(x, y, vy);
if (b) {
m_activeBullets.push_back(b);
} else {
std::cerr << "èŠå: 匟䞞ããŒã«æ¯æžïŒçºå°ãã¹ããã\n";
}
}
void updateAll() {
for (size_t i = 0; i < m_activeBullets.size(); ) {
Bullet* b = m_activeBullets[i];
b->update();
if (!b->isAlive) {
// 1. ããŒã«ãžè¿åŽïŒO(1)ïŒ
m_pool.deallocate(b);
// 2. vector ã®æ«å°Ÿãšå
¥ãæ¿ããŠé«éåé€ïŒswap-and-pop: O(1)ïŒ
m_activeBullets[i] = m_activeBullets.back();
m_activeBullets.pop_back();
} else {
++i;
}
}
}
size_t activeCount() const { return m_activeBullets.size(); }
size_t poolUsage() const { return m_pool.allocatedCount(); }
};
ð ç解床ãã§ãã¯ã¯ã€ãº
Q1. ã²ãŒã ã®å®è¡æïŒã¡ã€ã³ã«ãŒãäžïŒã«ç new / delete ã®å€çšãå³çŠãããæå€§ã®çç±ãšããŠãæãé©åãªãã®ã¯ã©ãã§ããïŒ
1. C++ã³ã³ãã€ã©ã new ãèŠã€ãããšèªåçã«æé©åãè§£é€ããŠããŸã仿§ã ãã 2. OSã®ããŒãã¢ãã±ãŒã¿ã¯å®è¡æéããã¬ãïŒé決å®è«çïŒäžã«ãæçåïŒãã©ã°ã¡ã³ããŒã·ã§ã³ïŒã«ãã空ã容éããã£ãŠãå²ãåœãŠäžèœã§ã¯ã©ãã·ã¥ããå±éºããããã 3. new ã§ç¢ºä¿ããã¡ã¢ãªã¯ delete ãåŒãã§ãOSã«è¿åŽãããªããã°ãCPUã«ååšãããã 4. ãã€ã³ã¿ã®ãããæ°ã new ãåŒã¶ãã³ã«è¥å€§åããŠ64bitãè¶
ããŠããŸããã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒOSã®ããŒãã¢ãã±ãŒã¿ã¯å®è¡æéããã¬ãïŒé決å®è«çïŒäžã«ãæçåïŒãã©ã°ã¡ã³ããŒã·ã§ã³ïŒã«ãã空ã容éããã£ãŠãå²ãåœãŠäžèœã§ã¯ã©ãã·ã¥ããå±éºããããã
æ£è§£ã¯ãOSã®ããŒãã¢ãã±ãŒã¿ã¯å®è¡æéããã¬ãäžã«ãæçåã«ãã空ã容éããã£ãŠãå²ãåœãŠäžèœã§ã¯ã©ãã·ã¥ããå±éºããããããã§ãïŒæ±çšã¢ãã±ãŒã¿ã¯æ§ã
ãªãµã€ãºã®èŠæ±ã«å¿ãããããç¹°ãè¿ãã® new/delete ã§ã¡ã¢ãªãè«é£ãç¶æ
ã«ãªããŸããã²ãŒã éçºã§ã¯åºå®é·ããŒã«ãã¹ã¿ãã¯ã¢ãã±ãŒã¿ã«ããããã¬ãŒã ããšã®ããŒãå²ãåœãŠããŒãã«æããã®ãéåã§ãã
Q2. ç¬èªã¡ã¢ãªããŒã«ã§å©çšãããããã¬ãŒã¹ã¡ã³ã newïŒplacement newïŒããšãåŸçä»ããã«é¢ãã説æãšããŠãæ£ãããã®ã¯ã©ãã§ããïŒ
1. ãã¬ãŒã¹ã¡ã³ã new ã¯ããŒãããèªå確ä¿ãããããéåžžéã delete ptr; ã§ç Žæ£ããªããã°ãªããªã 2. ãã¬ãŒã¹ã¡ã³ã new ã¯ã¡ã¢ãªç¢ºä¿ãè¡ããæå®ã¢ãã¬ã¹ã«ãªããžã§ã¯ããæ§ç¯ãããããç Žæ£æã¯ delete ã䜿ããæç€ºçãã¹ãã©ã¯ã¿ïŒptr->~T()ïŒãåŒã³ãã¡ã¢ãªã¯ããŒã«ãžè¿åŽãã 3. ãã¬ãŒã¹ã¡ã³ã new ã§æ§ç¯ãããªããžã§ã¯ãã¯ãã¹ãã©ã¯ã¿ãåŒã³åºãå¿
èŠããªããfree(ptr) ã ãã§å®å
šã«å®å
šã«ç Žæ£ã§ãã 4. ãã¬ãŒã¹ã¡ã³ã new 㯠C++17 ã§éæšå¥šãšãªããçŸåšã¯ std::make_shared 以å€ã®äœ¿çšãçŠæ¢ãããŠãã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒãã¬ãŒã¹ã¡ã³ã new ã¯ã¡ã¢ãªç¢ºä¿ãè¡ããæå®ã¢ãã¬ã¹ã«ãªããžã§ã¯ããæ§ç¯ãããããç Žæ£æã¯ delete ã䜿ããæç€ºçãã¹ãã©ã¯ã¿ïŒptr->~T()ïŒãåŒã³ãã¡ã¢ãªã¯ããŒã«ãžè¿åŽãã
æ£è§£ã¯ããã¬ãŒã¹ã¡ã³ã new ã¯ã¡ã¢ãªç¢ºä¿ãè¡ããæå®ã¢ãã¬ã¹ã«ãªããžã§ã¯ããæ§ç¯ãããããç Žæ£æã¯ delete ã䜿ããæç€ºçãã¹ãã©ã¯ã¿ïŒptr->~T()ïŒãåŒã³ãã¡ã¢ãªã¯ããŒã«ãžè¿åŽãããã§ãïŒãã delete ptr; ãåŒã¶ãšãOSã® free() ãèµ°ã£ãŠããŒã«å
šäœã®ãããã¡ãäžæ£ç Žå£ããŠå³æ»ã¯ã©ãã·ã¥ããŸããã¡ã¢ãªå²ãåœãŠãšãªããžã§ã¯ãã©ã€ããµã€ã¯ã«ãå®å
šã«åé¢ããã®ãC++äœã¬ã€ã€ã®ç¥é«ã§ãã
ð»ââïž ã·ãã¯ãC++ã©ã ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ã·ã¹ãã
ãã©ãŠã¶ã§JavaScriptãæå¹ã«ãããšããã©ãŠã¶å
ã€ã³ããŒããŒã²ãŒã ãšãã¥ã¬ãŒã¿ãã¡ã¢ãªãããå¯èŠåãUMLã¯ã©ã¹å³ã察話å解説ãç解床ã¯ã€ãºãèµ·åããŸãã
ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ãéå§ãã â