↓ Skip to main content
  1. Posts/

[设计模式] 组合模式(composite) 学习笔记

·546 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

目的是忽略单一对象和组合对象的不同。 有点像以前写过的用链表定义一个树结构,每个节点是一个val + 多个tree 。如果某个节点是叶子节点了,那么对应的tree都为NULL. 只不过这里用了更加面向对象的实现。

具体看代码:

详细代码
 1/* ***********************************************
 2Author :111qqz
 3mail: renkuanze@sensetime.com
 4Created Time :2018年08月28日 星期二 14时21分51秒
 5File Name :composite.cpp
 6************************************************ */
 7#include <iostream>
 8#include <list>
 9#include <string>
10using namespace std;
11
12class Component { // 为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为
13protected:
14    string name;
15public:
16    Component(string n) { name = n; }
17    virtual ~Component() {}
18    virtual void Add(Component* c) = 0;
19    virtual void Remove(Component* c) = 0;
20    virtual void Display(int depth) = 0;
21};
22
23class Leaf : public Component { // 在组合中表示叶节点对象,叶节点没有子节点
24public:
25    Leaf(string name) : Component(name) {}
26    void Add(Component* c){} // 叶节点没有Add功能,但这样做能使接口具备一致性,这就是透明方式,如果不加入Add和Remove方法,那就是安全方式。
27    void Remove(Component* c){} // 同上
28    void Display(int depth) { cout << name << "  " << depth << endl; }
29};
30
31class Composite : public Component { // 定义有枝节点行为,用来存储子部件
32private:
33    list<Component* > children;
34public:
35    Composite(string name) : Component(name) {}
36    void Add(Component* c) { children.push_back(c); }
37    void Remove(Component* c) { children.remove(c); }
38    void Display(int depth) {
39        cout << name << "  " << depth << endl;
40        for (auto c = children.begin(); c != children.end(); c++) {
41            (*c)->Display(depth+1);
42        }
43    }
44};
45
46int main() { // 客户端实现代码
47    Composite* root = new Composite("root");
48    root->Add(new Leaf("Leaf A"));
49    root->Add(new Leaf("Leaf B"));
50
51    Composite* comp = new Composite("Composite X");
52    comp->Add(new Leaf("Leaf XA"));
53    comp->Add(new Leaf("Leaf XB"));
54    root->Add(comp);
55
56    Composite* comp2 = new Composite("Composite XY");
57    comp2->Add(new Leaf("Leaf XYA"));
58    comp2->Add(new Leaf("Leaf XYB"));
59    comp->Add(comp2);
60
61    root->Display(1);
62
63    return 0;
64}

最后打印的结果为:

root 1 Leaf A 2 Leaf B 2 Composite X 2 Leaf XA 3 Leaf XB 3 Composite XY 3 Leaf XYA 4 Leaf XYB 4

Related

[C++11] promise && future leanrning notes

·322 words·1 min
用人话就是,主线程传给附属线程一个promise Object,然后主线程想要获取附属线程set给promise Object的值(也就是该线程返回的某个结果),需要通过主线程中的promise object 得到对应的future object(每个promise 对应一个 future),然后调用future 的get方法。如果附属线程没有执行作为参数传入的promise的set方法去返回结果,那么程序就会block住。

把二进制文件按字节读到vector中

·197 words·1 min
1 std::vector<unsigned char> readFromFile1(const char* filePath) { 2 FILE* file = fopen(filePath, "rb"); 3 std::vector<unsigned char> result; 4 if (file == nullptr) { 5 return result; 6 } 7 8 // 获取文件大小,尽量一次读完 9 size_t fileSize = getFileSize(file); 10 if (fileSize != 0) { 11 result.resize(fileSize); 12 size_t n = fread(&result[0], 1, fileSize, file); 13 assert(n <= fileSize); 14 if (n != fileSize) { 15 result.resize(n); 16 } 17 } 18 19 // 在读取过程当中,有可能文件大小有变化,再尝试读取 20 const size_t read_len = 1024; 21 char buf[read_len]; 22 for (;;) { 23 size_t n = fread(buf, 1, read_len, file); 24 result.insert(result.end(), buf, buf + n); 25 if (n < read_len) { 26 break; 27 } 28 } 29 fclose(file); 30 return result; 31 } 另外一种C++风格,但是性能较差的方法:

boost:property_tree 学习笔记

·254 words·1 min
先放资料: How to use boost::property_tree to load and write JSON How to iterate a boost property tree? 不出现key的方法遍历一个json文件: 详细代码 1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年08月17日 星期五 15时29分23秒 5 File Name :ptree.cpp 6 ************************************************ */ 7 #include <boost/property_tree/ptree.hpp> 8 #include <boost/property_tree/json_parser.hpp> 9 #include <bits/stdc++.h> 10 #include <vector> 11 using namespace std; 12 using boost::property_tree::ptree; 13 14 string indent(int level) { 15 string s; 16 for (int i=0; i<level; i++) s += " "; 17 return s; 18 } 19 20 void printTree (ptree &pt, int level) { 21 if (pt.empty()) { 22 cerr << "\""<< pt.data()<< "\""; 23 } 24 25 else { 26 if (level) cerr << endl; 27 28 cerr << indent(level) << "{" << endl; 29 30 for (ptree::iterator pos = pt.begin(); pos != pt.end();) { 31 cerr << indent(level+1) << "\"" << pos->first << "\": "; 32 33 printTree(pos->second, level + 1); 34 ++pos; 35 if (pos != pt.end()) { 36 cerr << ","; 37 } 38 cerr << endl; 39 } 40 41 cerr << indent(level) << " }"; 42 } 43 44 return; 45 } 46 int main() 47 { 48 ptree root; 49 read_json("terr.json",root); 50 printTree(root,0); 51 52 53 return 0; 54 55 }

c++11 function 与bind 学习笔记

·315 words·1 min
C++11 std::function 是一种通用、多态的函数封装,它的实例可以对任何可 以调用的目标实体进行存储、复制和调用操作 见下面的例子 1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年07月19日 星期四 17时41分00秒 5 File Name :bind.cpp 6 ************************************************ */ 7 #include <functional> 8 #include <iostream> 9 using namespace std; 10 float foo( int x,int y,int z){return x+y+z+1.;} 11 int main() 12 { 13 function<int(int,int)>func = foo; 14 int y = 10; 15 function<int(int)>fun = [&]( int value)->int 16 { 17 return 1+value+y; 18 }; 19 cout<<func(15,4,9)<<endl; 20 cout<<fun(8)<<endl; 21 return 0; 22 } std::bind 则是用来绑定函数调用的参数的,它解决的需求是我们有时候可 能并不一定能够一次性获得调用某个函数的全部参数,通过这个函数,我们可以将 部分调用参数提前绑定到函数身上成为一个新的对象,然后在参数齐全后,完成调 用