60

Zerosquare (./57) :
topics/108059-trolloscope-who-is-the-best/72#2159 ? cheeky

merci, c'est exactement ça ^^
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

61

Voila la partie interessante, merci Zero ^^

http://arstechnica.com/apple/2011/07/mac-os-x-10-7/10/#gc

(mince Jobs était encore en vie a cette époque..)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

62

Bon j'ai amélioré mon framework de ref-counting C++. Grâce à quelques hacks on peut écrire du code C++ comme en C# (et ça tombe bien parce que je code pas en C++ pour la vitesse, mais parce que j'ai pas le choix -- enfin pour la vitesse aussi un peu mais quand c'est important seulement).

Donc avec ce framework, on n'a qu'à utiliser des ref<Type> à la place des Type *. Partout où une 'ref' se balade, son refcount vient avec. On n'a plus besoin de faire de delete. Ainsi ces deux sont équivalents :
Texture *t = new Texture();
t->method();
delete t;

ref<Texture> t = newref Texture();
t->method();

Une 'ref' peut être utilisée sans conversion comme un pointeur standard. Par contre dans cet état il est 'détaché', c'est à dire qu'il n'est pas ref-counté. L'utilité est de le passer à des framework ou libs externes qui ne font pas de gestion de mémoire.
void draw(Sprite *s) {
    ...
}

ref<Sprite> s = ...;
draw(s);

// Ou bien
Sprite stackSprite;
draw(&stackSprite);

Il est également possible d'attacher (rendre "ref-counté") un objet créé par une lib externe. On en devient alors propriétaire et il sera supprimé dès qu'il n'est plus référencé.
Sprite *createSprite() {
    return new Sprite(...);
}

ref<Sprite> monSprite = mkref(createSprite());


On n'est pas obligé de le passer à mkref, mais à ce moment le sprite ne sera pas ref-counté (typiquement utile lorsqu'une de nos fonctions accepte des ref<Truc> mais qu'on y passe un Truc* ; à ce moment on suppose que le Truc* est managé par l'appelant).
void fonction(ref<Texture> tex) {
    ...
}

Texture t;
fonction(&t);


Il est possible d'écrire "newref" pour créer une nouvelle instance d'un objet "ref-counté".
ref<Texture> carTexture = newref FileTexture("voiture.png");
ref<Sprite> carSprite = newref Sprite(carTexture, 80, 35);
// Egal à
// ref<Sprite> carSprite = mkref(new Sprite(...));

Au final, ça signifie en pratique qu'il n'y a vraiment plus de quoi se soucier de rien. Il suffit d'appeler newref pour créer les objets et plus jamais delete, et d'utiliser des ref<Type> à la place des Type*. Ca passe de façon transparente dans les frameworks externes. Vraiment agréable quand on veut pas se faire chier smile En plus ça pourrait être utilisé pour tracker tous les objets créés dans l'application et voir si certains ont été leakés (références circulaires).

Question implémentation j'aime bien mon hack pour le newref, regardez plutôt :
struct __MkrefHelper {
	template<class T>
	ref<T> operator * (T *detachedRef) {
		return ref<T>(detachedRef, true);
	}
};
#define newref __MkrefHelper() * new 

Oui oui on multiplie le résultat du new par un objet spécial, dont la multiplication est surchargée pour créer une référence avec son opérande. grin
Bref pour ceux que ça intéresse ->
template<class T> class ref { void incref() { if (counter) (*counter)++; } void decref() { if (counter && --(*counter) == 0) delete ptr, delete counter; } public: T *ptr; unsigned *counter; ref() : ptr(0), counter(0) {} ref(const ref<T> &ref) : ptr(ref.ptr), counter(ref.counter) { incref(); } template<class U> ref(const ref<U> &ref) : ptr(ref.ptr), counter(ref.counter) { incref(); } ref(T *ptr) : ptr(ptr), counter(0) {} ref(T *ptr, bool owned) : ptr(ptr) { counter = ptr ? new unsigned(1) : 0; } // Nil-able ref(int) : ptr(0), counter(0) {} ~ref() { decref(); } template<class U> ref<T> &operator = (const ref<U> &ref) { // Using the same logic may free the original object if counter = 1 if (ref.ptr == ptr) return *this; // Else, do the equivalent of destructing "this" and constructing with "ref" decref(); ptr = ref.ptr, counter = ref.counter; incref(); return *this; } ref<T> &operator = (const ref<T> &ref) { // Using the same logic may free the original object if counter = 1 if (ref.ptr == ptr) return *this; // Else, do the equivalent of destructing "this" and constructing with "ref" decref(); ptr = ref.ptr, counter = ref.counter; incref(); return *this; } ref<T> &operator = (T *newPtr) { decref(); ptr = newPtr, counter = 0; return *this; } void operator delete (void *) { throw "Must not delete refs!"; } operator T* () const { return ptr; } T* operator -> () const { return ptr; } T& operator * () const { return *ptr; } bool operator == (const ref<T> &ref) const { return ref.ptr == ptr; } bool operator != (const ref<T> &ref) const { return ref.ptr != ptr; } }; template<class T> ref<T> mkref(T *obj) { return ref<T>(obj, true); } struct __MkrefHelper { template<class T> ref<T> operator * (T *detachedRef) { return ref<T>(detachedRef, true); } }; #define newref __MkrefHelper() * new
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741