AICharacter 클래스에 FRandomStream 추가 및 BeginPlay 시 고유 ID 기반 시드 초기화.Wait Random 태스크에서 FRandomStream을 사용하여 정해진 시간 내에서 랜덤 값을 블랙보드로 저장Wait Blackboard Time 태스크를 활용해서 Idle 상태 구현
정의
private / protected 멤버에 접근할 수 있도록 하는 키워드특징
private,protected)에도 접근 가능사용법
class Box {
private:
int width;
public:
Box(int w) : width(w) {}
// friend 함수 선언
friend void PrintWidth(const Box& b);
};
void PrintWidth(const Box& b) {
cout << "Width: " << b.width << endl;
}
class A {
public:
friend class B;
};
class B {
private:
int y;
};
class A;
class B {
public:
void AccessA(A& a);
};
class A {
private:
int secret = 42;
friend void B::AccessA(A& a); // B의 특정 함수만 허용
};
void B::AccessA(A& a) {
cout << "Accessing secret: " << a.secret << endl;
}
-> B의 멤버 함수인 AccessA에서 A의 private 멤버 변수인 secret에 접근 가능
std::mutex, std::lock_guard 등을 사용해 임계 구역 보호std::vector, std::map, std::queue 등을 직접 뮤텍스에 감싸서 사용#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
std::vector<int> data;
std::mutex mtx;
void worker(int id) {
std::lock_guard<std::mutex> lock(mtx); // 임계 구역 보호
data.push_back(id);
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
for (int v : data)
std::cout << v << " "; // 1 2
}
std::atomic을 기반으로 동작lock() 없이도 여러 쓰레드가 동시에 push/pop 가능 -> 효율적#include <atomic>
#include <memory>
template <typename T>
class LockFreeStack {
struct Node {
T data;
Node* next;
Node(T const& d) : data(d), next(nullptr) {}
};
std::atomic<Node*> head{nullptr};
public:
void push(T const& value) {
Node* newNode = new Node(value);
newNode->next = head.load(std::memory_order_relaxed);
while (!head.compare_exchange_weak(newNode->next, newNode));
}
std::shared_ptr<T> pop() {
Node* oldHead = head.load();
while (oldHead && !head.compare_exchange_weak(oldHead, oldHead->next));
return oldHead ? std::make_shared<T>(oldHead->data) : nullptr;
}
};
push() / try_pop() 가능insert()/erase()/find() 안전push() 가능try_pop()은 가장 높은 우선순위 원소를 반환erase() 같은 임의 원소 제거 불가-> TBB의 concurrent 컨테이너들은 삽입/탐색/읽기 위주의 병렬 연산에 강점