C++复习

读《google C++风格指南》有感

2018-10-29  本文已影响2人  凉拌姨妈好吃

1. 复习内容

1.1 匿名命名空间

字面意思:声明命名空间时忽略名字
编译器内部会为这个命名空间生成一个唯一的名字和using指令

namespce {
    char c;
    int i;
    double d;
 }

所以上面的代码在编译器内部类似于:

 namespace __UNIQUE_NAME_ {
     char c;
     int i;
     double d;
     }
 using namespace __UNIQUE_NAME_;

它和静态变量的相似之处?
匿名命名空间也具有内连接属性,也就是说名称的作用域被限制在当前文件中,无法在其他文件使用extern来扩展作用域
它和静态变量相比更优在哪?
对于多个同一文件的标识符函数只需要用一个匿名空间来声明,不需要多次输入static

1.2 如何引用命名空间
// 方式一
ace::Mutex mutex;
// 方式二
using ace::Mutex;
// 方式三
using namespace ace;

对于上面三种方式的选择应由一到三,因为越往后产生命名冲突的可能越大

1.3 override与final
1.4 访问者模式
package yanbober.github.io;

import java.util.ArrayList;
import java.util.List;

//Vistor(抽象访问者)
interface Vistor {
    void visit(ConcreteElementNodeA node);
    void visit(ConcreteElementNodeB node);
}
//ConcreteVisitor(具体访问者)
class ConcreteVisitorA implements Vistor {
    @Override
    public void visit(ConcreteElementNodeA node) {
        System.out.println(node.operationA());
    }

    @Override
    public void visit(ConcreteElementNodeB node) {
        System.out.println(node.operationB());
    }
}

class ConcreteVisitorB implements Vistor {
    @Override
    public void visit(ConcreteElementNodeA node) {
        System.out.println(node.operationA());
    }

    @Override
    public void visit(ConcreteElementNodeB node) {
        System.out.println(node.operationB());
    }
}
//Element(抽象元素)
abstract class ElementNode {
    public abstract void accept(Vistor vistor);
}
//ConcreteElement(具体元素)
class ConcreteElementNodeA extends ElementNode {
    @Override
    public void accept(Vistor vistor) {
        vistor.visit(this);
    }

    public String operationA() {
        return "ConcreteElementNodeA";
    }
}

class ConcreteElementNodeB extends ElementNode {
    @Override
    public void accept(Vistor vistor) {
        vistor.visit(this);
    }

    public String operationB() {
        return "ConcreteElementNodeB";
    }
}
//ObjectStructure(对象结构)
class ObjectStructure {
    private List<ElementNode> nodeList = new ArrayList<>();

    public void action(Vistor vistor) {
        for (ElementNode node : nodeList) {
            node.accept(vistor);
        }
    }

    public void add(ElementNode node) {
        nodeList.add(node);
    }
}
//客户端
public class Main {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.add(new ConcreteElementNodeA());
        objectStructure.add(new ConcreteElementNodeB());

        Vistor vistor = new ConcreteVisitorA();
        objectStructure.action(vistor);
    }
}

参考:
设计模式(行为型)之访问者模式(Visitor Pattern)
23种设计模式(9):访问者模式

1.5 何时捕获异常

我们只能捕获我们能够处理的异常,能够恢复的异常将它捕获后恢复,像不能恢复的如,越界等就不要捕获了。
对使用 C++ 异常处理应具有怎样的态度?

1.6 可重入函数
1.7 杂项
int x{0};
auto f1 = [=]() mutable {x = 42;};  // okay, 创建了一个函数类型的实例
auto f2 = [=]()         {x = 42;};  // error, 不允许修改按值捕获的外部变量的值
// 存储自由函数
std::function<void(int)> f_display = print_num;
f_display(-9);
 
// 存储 lambda
std::function<void()> f_display_42 = [](){ print_num(42); };
f_display_42();
 

2. 代码风格的思考(仅针对客户端)

2.1 在别人代码上进行迭代
2.2 自己写代码

下面以这个页面来对代码做一个梳理:
首先有一个头部主要是放活动图片/标题等,中部是一个横向scroll,上面的btn可以刷新下面的纵向scroll里的节点信息


local tableItemsSel = {
  { data = data,
    point = nil,
    pos = {x = 0,y = 0}
}
}

设定一个值为预加载范围,如果在范围内就让节点可见,不在范围内就让节点不可见且插入缓存tableItemsSpare

local scrollH = scroll的高度
local tableShowH = {beginY = math.max(0,scroll的y轴偏移-0.5*scrollH),endY = scroll的y轴偏移+1.5*scrollH,}

白色区域为我们的初始可视区域,红色区域就是我们现在扩大了的可视区域,超过这个可视区域,就让节点不可见且插入缓存tableItemsSpare


if v.pos.y < tableShowH.beginY or v.pos.y > tableShowH.endY then
                v.point:setVisible(false)
                table.insert(self.tableItemsSpare,v.point)
                v.point = nil
end

如果缓存数组里有节点就取出设为可见,再初始化它。否则新建节点


上一篇下一篇

猜你喜欢

热点阅读