2013321

candidates = "state node seelog state runstate libtime start stop enable onedeploy deploy make quit FeedAssistant FeedDispatcher FeedNews FeedMini FeedClass FeedGroup FeedFocus FeedSink FeedMark".split()

python以目录来组织模块, 就是所谓的包. 用包的一大好处: 可以解决名字空间冲突的问题, 即文件重名问题. 
    下面主要说3点: 
    1. 如何使一个目录变成包,如何import 
           目录下放一个__init__.py文件(内容可以为空), import包内模块的时候使用"."分割, 比如import Apackage.Amodule 
    2. __init__.py的__all__变量 
           __all__指定的是指此包被import * 的时候, 哪些模块会被import进来 
    3. __init__.py的__path__变量 
           __path__指定了包的搜索路径
__init__.py可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py中也可以设置相应的内容,
以*导入时,package内的module是受__init__.py限制的。
我们在subPack1文件夹下的__init__.py文件中写

__all__ = ['module_13', 'module_12']

rom package1.subPack1 import *     只会导入module_12 13文件


(3) 如果根本不知道文件所在目录,就需要在根目录下进行查找(查找整个硬盘空间),但是由于根目录下某些文件(bin、sbin、boot、dev、initrd、lib)没有查找价值,因而要将其排除在查找范围之外
# cd /
grep -rin findcontents `ls | grep -vE 'bin|boot|dev|initrd|lib'`



用户定义一个empty class (空类),当C++ 处理过它之后,如果你自己没声明,编译器就会为它声明(编译器版本的)一个copy 构造函数、一个copy assignment操作符和一个析构函数此外如果你没有声明任何构造函数,编译器也会为你声明一个default 构造函数。所有这些函数都是public 且inline 。

class Empty { };

这就好像你写下这样的代码:

class Empty {
 public:
  Empty() { ... }
  Empty(const Empty& rhs) { ... )
  -Empty( ) { ... }
  Empty& operator=(const Empty& rhs) { ... }
};


某些对象是独一无二的(比如房子),你应该禁用copy 构造函数或copy assignment 操作符,可选的方案有两种
(1)定义一个公共基类   privaate copying函数

(2) 创建一个宏,并将之放到每一个独一无二对象的private中,该宏为:

// 禁止使用拷贝构造函数和 operator= 赋值操作的宏
// 应该类的 private: 中使用
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)

这种方法比第一种方法好,google C++编程规范中提倡使用该方法。


条款07: 为多态基类声明virtual 析构函数

本条款阐述了一个程序员易犯的可能导致内存泄漏的错误,总结了两个程序员应遵守的百编程原则:

(1)polymorphic (带多态性质的) base classes 应该声明一个virtual 析构函数。如果

class 带有任何virtual 函数,它就应该拥有一个virtual 析构函数。这样,但用户delete基类指针时,会自动调用派生类的析构函数(而不是只调用基类的析构函数)。

(2)Classes 的设计目的如果不是作为base classes 使用,或不是为了具备多态性(polymorphically) ,就不该声明virtual 析构函数。这是因为,当用户将一个函数声明为virtual时,C++编译器会创建虚函数表以完成动态绑定功能,这将带来时间和空间上的花销。


[1] const_cast<T>(expression) : 移除变量的const属性

[2] dynamic_cast<T>(expression) : 安全向下转型,即:基类指针/引用到派生类指针/引用的转换如果源和目标类型没有继承/被继承关系,编译器会报错否则必须在代码里判断返回值是否为NULL来确认转换是否成功。

[3] reinterpret_cast<T>(expression):底层转换

[4] static_cast<T>(expression):强迫隐式转换,如,将non-const对象转换为const对象,将int转换为double类型。


在C++继承中,virtual函数是动态绑定的,调用的函数跟指针或者引用实际绑定的那个对象有关,而non-virtual函数是静态绑定的,调用的函数只跟声明的指针或者引用的类型相关

指针和引用只知道自己类型的相关信息!!

 
class B{
 public:
  void func(){ cout<<“B”;}
};

class D:public B{
 public
  void func() { cout<<“D”;}

};

下面是对B和D的使用:

D dObject;
B* basePtr = &dObject;
D* dOjbectPtr = &dObject;

看下面这两种调用方式:

basePtr->func();

dOjbectPtr->func();

你会发现打印结果为:

B

D

 

(1) 如果class之间的继承关系是private。编译器不会自动将一个derived class对象转化为一个base class对象。由private base class继承而来的所有成员,在derived class中都会变成private属性,纵使它们在base class中原来是protected或public属性。

线程池模式一般分为两种:L/F领导者与跟随者模式、HS/HA半同步/半异步模式。

HS/HA 半同步/ 半异步模式 :分为三层,同步层、队列层、异步层,又称为生产者消费者模式,主线程处理I/O事件并解析然后再往队列丢数据,然后消费者读出数据进行应用逻辑处理;
优点:简化编程将低层的异步I/O和高层同步应用服务分离,且没有降低低层服务性能。集中层间通信。
缺点:需要线程间传输数据,因此而带来的动态内存分配,数据拷贝,语境切换带来开销。高层服务不可能从底层异步服务效率中获益。
L/F 领导者跟随者模式 :在LF线程池中,线程可处在3种线程状态之一: leader、follower或processor。处于leader状态的线程负责监听网络端口,当有消息到达时,该线程负责消息分离,并从处于 follower状态中的线程中按照某种机制如FIFO或基于优先级等选出一个来当新的leader,然后将自己设置为processor状态去分配和处 理该事件。处理完毕后线程将自身的状态设置为follower状态去等待重新成为leader。在整个线程池中同一时刻只有一个线程可以处于leader 状态,这保证了同一事件不会被多个线程重复处理。
缺点:实现复杂性和缺乏灵活性;
优点:增强了CPU高速缓存相似性,消除了动态内存分配和线程间的数据交换。

 


 

原文地址:https://www.cnblogs.com/tangr206/p/2974339.html