åç½®ã:RAII ã£ã¦?
C++ è¨èªã«ã¯ RAII; Resource Acquisition is Initialization ã¨ããèãæ¹ãããã¾ã。ããã¯ã©ããããã¨ã§ãããã。
#define ARRY_SZ (5)
int32_t p_arry = (int32_t *)malloc(sizeof(int32_t) * ARRY_SZ);
p_arry[0] = 1;
p_arry[1] = 2;
p_arry[2] = 3;
p_arry[3] = 4;
p_arry[4] = 5;
for (size_t idx=0; idx<ARRY_SZ; ++idx) {
printf("p_arry[%zu]=%" PRId32 "\n", idx, p_arry[idx]);
}
ãããã、Cã§ãã¼ã確ä¿ããã³ã¼ãã§ãã、ãã®ã³ã¼ãç㯠free(p_arry)
ãå¼ã³åºãå¿ãã¦ãããã、ããããããã¡ã¢ãªã¼ããªã¼ã¯ããããããã¾ãã。ã¾ã、for æã§å¤ã表示ããåã« p_arry[n] = n+1;
ã®å½¢å¼ã§ç¢ºä¿ããé åãåæåãã¦ãã¾ãã、ããã§åæåãå¿ãã¦ãããã©ãã§ããã。æªåæåã®é åãèªã¿åºããã¨ããã®ã¯ Undefined Behavior ãªã®ã§、é¼»ããæªéãåºãããããã¾ãã。
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cinttypes>
#include <new>
#include <initializer_list>
class HeapArray {
private:
std::int32_t *values = nullptr;
std::size_t size = 0;
public:
HeapArray() = delete;
HeapArray(std::initializer_list<std::int32_t> init) {
this->values = new(std::nothrow) std::int32_t[init.size()];
if (this->values == nullptr) {
return;
}
this->size = init.size();
std::size_t idx=0;
for (auto&& v : init) {
this->values[idx] = v;
++idx;
}
}
~HeapArray() { delete[] this->values; };
void debug() {
for (std::size_t idx=0; idx<this->size; ++idx) {
std::printf("values[%zu]=%" PRId32 "\n", idx, this->values[idx]);
}
}
};
int main() {
HeapArray test {1, 2, 3, 4, 5};
test.debug();
return 0;
}
ã§ã¯ãã¡ãã® C++ ã®ã³ã¼ãã¯ã©ãã§ããã。ã¯ã©ã¹ã«ãã¦ãããã¨ã§、å ç¨ã® C ã®ã³ã¼ãã¨ãã£ã¦ããã¨ã¯åãã§ãã、å¤æ°å®£è¨ããã ãã§ã³ã³ã¹ãã©ã¯ã¿ã§ãã¼ã確ä¿ããã¾ãã、ã¹ã³ã¼ãããå¤ãããèªåã§ãã¹ãã©ã¯ã¿ãå¼ã°ãã¦ãã¼ããéæ¾ãã、ã¾ã、åæååãªã¹ããªãã§å¤æ°å®£è¨ããã¨ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã delete ãã¦ããã®ã§ã³ã³ãã¤ã«ãéããªãã®ã§、ããã°ã©ãã«åæåãå¼·è¦ã§ãã¾ã。
prog.cc: In function 'int main()': prog.cc:36:15: error: use of deleted function 'HeapArray::HeapArray()' 36 | HeapArray test_2; | ^~~~~~ prog.cc:13:5: note: declared here 13 | HeapArray() = delete; | ^~~~~~~~~ãã®ãããªã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãããã§ãã。
ä»åã¯ãã£ã¦ã¾ããã、ããã§æ´ã« unique_ptr ãªã©ã¹ãã¼ããã¤ã³ã¿ä½¿ãã¨ãã£ã¨è¯ãããããã¾ããã。
ãããã std::int32_t *values = new std::int32_t[5] {1, 2, 3, 4, 5};
ã¨ãããã° new ã ãã§é å確ä¿ã¨åæåãåæã«ã§ããã ã、ã¨ãã¯ç®ãçã£ã¦ãã ãã……。
RAII ã«ãããªã½ã¼ã¹ç®¡ç、ä»ã®è¨èªã«ããã£ãããã¾ã。ãã¨ãã° Pyton ã® with æ§æ。
with open("file.txt") as f:
print(f.read())
ãã®å ´å、open(2) ã§ç¢ºä¿ãããªã½ã¼ã¹ãå¤æ° f ã«ç´ä»ãã¦ç®¡çããã¦、with æ§æã®ã¤ã³ãã³ããããã¯ã®ã¹ã³ã¼ãããå¤ããã¨、èªå㧠close(2) ãè£ã§å¼ã°ãã¦ãªã½ã¼ã¹ãéæ¾ããã¾ã。close å¼ã³å¿ãããªãã¦ãã£ã¡ã便å©ã§ãã。
C 㧠RAII
C ããã°ã©ãã¼ã¯ãã®ãããªã¤ãã£ãªã ã®æ©æµã«ä¸ããªãã®ã§ãããã。ãã、å®ã¯ã³ã³ãã¤ã©æ¡å¼µã«ãã£ã¦ã¯、ãã®ãããªæ¸ãæ¹ãå¯è½ã«ãªãã®ã§ã。#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
static inline void dtor(void *p) {
free(*(void **)p);
puts("freed!");
}
#define ARRY_SZ (5)
int main() {
__attribute__((cleanup(dtor))) int32_t *p_arry = (int32_t *)malloc(sizeof(int32_t)*ARRY_SZ);
}
ããããã® __attribute__((cleanup(func)))
ã§ã。ä¸è¦ãã®ã³ã¼ã㯠p_arry ã«æ ¼ç´ãããã¼ãããªã¼ã¯ãã¦ããã§ãã、å®ã¯ã¡ãã㨠dtor é¢æ°ãå¼ã°ãã¦ãã¾ã。ãã®è¨¼æ ã«、ãã®ã³ã¼ããã³ã³ãã¤ã«・å®è¡ããã¨ã³ã³ã½ã¼ã«ã« freed!
ã¨è¡¨ç¤ºãããã¯ãã§ã。
ã¨ããã§、ãã®ã³ã¼ãã ã¨ç¢ºä¿ããé åã¯æªåæåã®ã¾ã¾ã§ã。ããã§、次ã®ããã«ãã¦ã¿ã¾ã。
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#include <starg.h>
#include <stdlib.h>
#include <stdio.h>
static inline void ctor(int32_t *p, size_t sz, ...) {
va_list ap;
va_start(ap, sz);
for (size_t idx=0; idx<sz; ++idx) {
p[idx] = va_arg(ap, int32_t);
}
va_end(ap);
}
static inline void dtor(void *p) {
free(*(void **)p);
puts("freed!");
}
#define CTOR_HEAP_ARRY(var, sz, ...) \
__attribute__((cleanup(dtor))) int32_t *var = (int32_t *)malloc(sizeof(int32_t)*sz); \
ctor(var, sz, __VA_ARGS__)
#define ARRY_SZ (5)
int main() {
CTOR_HEAP_ARRY(p_arry, ARRY_SZ, 1, 2, 3, 4, 5);
for (size_t idx=0; idx<ARRY_SZ; ++idx) {
printf("p_arry[%zu]=%" PRId32 "\n", idx, p_arry[idx]);
}
}
ã©ãã§ãããã!ãã¼ã確ä¿ã¨å ±ã«åæåãã§ãã¾ããã!ããã¾ããã!
ããã§ç¨æãããã¯ãã使ã£ã¦ããããªãã£ããã©ãããã®、ã¨ã、ãããããã®ãã¯ãçµæ§å±éºãããªã?ã¨ã、ããããè¨ããããã¨ãããã¨æãã¾ã。initializer list ã§ãããããªãã¨ãå¯å¤é·å¼æ°ã§å®ç¾ãããã¨ãã¦ã¨ã©ã¼ãã§ãã¯ããµãã£ã¦ãã®ã§、ãããã¡ãªã¼ãã¼ã©ã³ã®å±éºæ§ãããã¾ã。ã ãã§ãã。
ã¯ã。ã¿ã㪠Rust ã¨ã使ããã。