In the Javascript, the attribute of an object can be added as your wish. It is one of advantages better than static programing languages. In fact, the techology
is supported by an dictionary structure. The following code is simply implement by me. Just add an dictionary member into a class, C++ also can get the features.
So, dynamic or static is relative.
//dict.h
#ifndef DICT_H
#define DICT_H
#define KEY_MAX_LEN 1024
struct _entry_ {
int key_len;
char key[KEY_MAX_LEN + 1];
int val_len;
void *val;
struct _entry_ *next;
//friend class Dictionary;
};
typedef struct _entry_ Entry;
class Dictionary {
private:
Entry *head;
Entry *current;
public:
Dictionary();
Dictionary(Dictionary& d);
~Dictionary();
void add(char *key, int key_len, void *pVal, int val_len);
void remove(char *key);
Entry *lookup(char *key);
int isEmpty();
Entry *getFirstEntry();
int hasMore();
Entry *getNextEntry();
Dictionary& operator+(Dictionary& dict);
};
#endif
//dict.cpp
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "Dict.h"
using namespace std;
Dictionary::Dictionary() {
head = NULL;
current = NULL;
}
Dictionary::Dictionary(Dictionary& d) {
Entry *p = NULL;
head = NULL;
current = NULL;
for (p = d.getFirstEntry(); d.hasMore(); p = d.getNextEntry())
this->add(p->key, p->key_len, p->val, p->val_len);
}
Dictionary::~Dictionary(){
Entry *p = NULL;
if (head) {
for (p = head; p; ){
current = p;
p = p->next;
free(current->val);
delete current;
}
}
}
void Dictionary::add(char *key, int key_len, void *pVal, int val_len) {
//initialize an entry
Entry *p = new Entry();
memset(p, 0, sizeof(Entry));
p->next = NULL;
//create an entry
p->key_len = (key_len > KEY_MAX_LEN) ? KEY_MAX_LEN : key_len;
memcpy(p->key, key, p->key_len);
p->val_len = val_len;
p->val = (void*)malloc(p->val_len * sizeof(unsigned char));
memset(p->val, 0, p->val_len);
memcpy(p->val, pVal, p->val_len);
//insert the entry into the list
p->next = head;
head = p;
}
void Dictionary::remove(char *key) {
Entry *p = NULL;
Entry *q = NULL;
for (p = head, q = p; p; p = p->next){
if (strcmp(p->key, key) == 0)
break;
else
q = p; // prev
}
//found
if (p) {
// first entry
if (p == head)
head = p->next;
else{
q->next = p->next;
}
delete p;
}
}
Entry * Dictionary::lookup(char *key) {
Entry *p = NULL;
for (p = head; p; p = p->next){
if (strcmp(key, p->key) == 0) break;
}
return p;
}
int Dictionary::isEmpty(){
if (!head)
return 1;
else return 0;
}
Entry *Dictionary::getFirstEntry() {
current = head;
return current;
}
int Dictionary::hasMore() {
return current ? 1 : 0;
}
Entry * Dictionary::getNextEntry() {
current = current->next;
return current;
}
Dictionary& Dictionary::operator +(Dictionary& dict) {
Entry *p = NULL;
for (p = dict.getFirstEntry(); dict.hasMore(); p = dict.getNextEntry())
this->add(p->key, p->key_len, p->val, p->val_len);
return (*this);
}
//test
int main(int argc, char *argv[]){
char key[256];
char val[256];
Dictionary dict;
while (1) {
memset(key, 0, 256);
cin>>key;
if (strcmp(key, "end") == 0) break;
memset(val, 0, 256);
cin>>val;
dict.add(key, strlen(key), (void*)val, strlen(val));
}
Entry *p = NULL;
//dict.remove("name");
/*p=dict.lookup("name");
if (p){
memset(val, 0, 256);
memcpy(val, p->val, p->val_len);
cout<<p->key<<": "<<val<<endl;
}
cout<<"Dictionary:"<<endl;
for (p = dict.getFirstEntry(); dict.hasMore(); p=dict.getNextEntry()) {
memset(val, 0, 256);
memcpy(val, p->val, p->val_len);
cout<<"["<<p->key<<"] -> "<<val<<endl;
}*/
Dictionary d;
cout<<"The dictionary d is "<<(d.isEmpty() ? "empty" : "not empty")<<endl;
Dictionary dd = d+dict;
cout<<"Dictionary:"<<endl;
for (p = dd.getFirstEntry(); dd.hasMore(); p=dd.getNextEntry()) {
memset(val, 0, 256);
memcpy(val, p->val, p->val_len);
cout<<"["<<p->key<<"] -> "<<val<<endl;
}
return 0;
}