C++关键字explicit

在只有一个参数的构造函数时,直接对一个对象做赋值操作”=”, 有可能会执行一个隐式
转换,即调用只要一个参数的构造函数。这个过程是自动进行的,而不需要显式强制装换

C++提供了关键字 explicit,关闭了这种特性,则只可以显式转换。

如果不关闭这个特性,还有可能会执行以下的转换(以下面的my_class1为例子:
1. 将my_class1对象初始化为int类型时
1. 将int值赋值给my_class1对象时
1. 将int值传递给接收my_class1参数的函数时
1. 返回值被声明为my_class1的函数试图返回int值
1. 上述任意一种情况下,使用可转换为int类型的内置类型时

具体例子:

#include <iostream>
#include <string>

using namespace std;

class my_class1
{
public:
    my_class1() {
        mem_ = 0;
    }

    my_class1(int a) {
        mem_ = a;
    }

    void display() {
        cout << "mem_ = " << mem_ << endl;
    }

private:
    int mem_;
};

class my_class2
{
public:
    my_class2() {
        mem_ = 0;
    }

    explicit my_class2(int a) {
        mem_ = a;
    }

    void display() {
        cout << "mem_ = " << mem_ << endl;
    }

private:
    int mem_;
};


int main()
{
    my_class1 a;
    a.display();

    my_class1 b;
    b = 3;
    b.display();

    my_class2 c;
    c.display();

    /* Not allow
    my_class2 d;
    d = 4;
    d.display();
    */
}

C++静态变量

C++静态变量有三种:

  1. 无连接性的
  2. 内部连接性的
  3. 外部连接性的

首先看下面的代码:

#include <iostream>

using namespace std;

const int local_int = 10;
extern const int global_int = 20;
int global = 1000;
static int one_file = 2000;

void func1()
{
    int fun_val = 1;
    static int static_fun_val = 2;

    cout << endl << "func1: " << endl;
    cout << "global : " << global << endl;
    cout << "one_file : " << one_file << endl;
    cout << "fun_val : " << fun_val << endl;
    cout << "static_fun_val : " << static_fun_val << endl;

    fun_val++;
    static_fun_val++;
}

void func2()
{
    cout << endl << "func2: " << endl;
    cout << "global : " << global << endl;
    cout << "one_file : " << one_file << endl;
}


int main()
{
    func1();
    func1();

    func2();

    return 0;
}

运行结果是:

func1: 
global : 1000
one_file : 2000
fun_val : 1
static_fun_val : 2

func1: 
global : 1000
one_file : 2000
fun_val : 1
static_fun_val : 3

func2: 
global : 1000
one_file : 2000

在这里, glocal 是一个链接性为外部的静态变量,即其他文件中也可以使用global这个变量。
而one_file通过使用static关键字,把它的链接性设为内部的,则只有在这个文件内可以使用。

而在func1里面的两个变量: fun_val 和 static_fun_val:
fun_val 是函数执行时创建的一个变量,
而static_fun_val 是即使函数不执行,也会保留在内存中。而且它的初始化只会执行一次。

另外,这里还要注意的是:
const默认是内部链接属性,即定义为const的变量只可以在本文件内使用。
如果要给其他文件使用的话,需要加上extern。

C++模板函数匹配顺序

C++模板函数有的匹配顺序主要如下:

  1. 常规函数
  2. 显式具体化函数
  3. 显式实例化函数
  4. 常规模板

注意:模板实例化在template后面是没有加<>的,而模板具体化后面是有加的。
模板实例化是一个声明,不能带函数体的。

模板实例化的具体作用还不是很清楚,但是知道有以下的一个作用:
根据 “在同一文件中使用同类型的显示实例化和显示具体化会报错的特点”,先声明显示实例化,则后面的显示具体化如果存在,会报错,从而防止具体化该型模版!!

示例代码:

#include <iostream>
#include <string>

using namespace std;

//模板函数
template <typename T>
void display(T t)
{
    cout << "sizeof(T) = " << sizeof(T) << endl;
    cout << "template function" << endl;
    cout << "value = " << t << endl;
}

// 显式具体化模板函数
template <>
void display<string> (string t)
{
    cout << "template function for string" << endl;
    cout << "value = " << t << endl;
}

// 显式实例化
template void display<double> (double);

// 非模板函数
void display(float t)
{
    cout << "function for float" << endl;
    cout << "value = " << t << endl;
}

int main()
{
    // 调用模板函数
    int i = 10;
    display<int> (i);

    //调用显式具体化函数
    string str = "test";
    display(str);

    //调用非模板函数
    float f = 8.88;
    display(f);

    double d = 1.11;
    display(d);


    return 0;
}
// vim: set et ts=4 sts=4 sw=4:

输出结果是:

sizeof(T) = 4
template function
value = 10
template function for string
value = test
function for float
value = 8.88
sizeof(T) = 8
template function
value = 1.11

修改SSH的默认端口

今天无意中查看一下vps的登录日志/var/log/auth.lg
不看还好,一看吓一跳。每隔一分钟就有人尝试登录一次。

虽然现在是通过秘钥进行登录,而且还是通过root用户进行登录的。
感觉存在严重的安全隐患,必须想想办法了。


1. 限制root用户登录

首先,限制root用户登录。
这样用自己创建的用户,起码用户名对方是不知道的,大大减少了被破解的危险。
修改配置文件:

#PermitRootLogin yes
PermitRootLogin no

2. 修改端口

众所周知,ssh默认端口是22,把22修改成其他,可以降低风险。
如把端口修改成8888,修改配置文件:

#Port 22
Port 8888

修改deb包里的内容并重新打包

以安装有道词典为例子:
原文连接为:http://www.cnblogs.com/scplee/archive/2016/05/13/5489024.html

因为旧版本的包在新版本的系统里面所依赖的包有所不同,所以要更新一下依赖:

  1. 从官方下载Ubuntu版本的deb包:youdao-dict_1.1.0-0-ubuntu_amd64.deb
  2. 创建youdao-dict目录,把该deb包解压到youdao-dict目录:
    dpkg -X ./youdao-dict_1.1.0-0-ubuntu_amd64.deb youdao-dict
  3. 解压deb包中的control信息(包的依赖就写在这个文件里面)
    dpkg -e ./youdao-dict_1.1.0-0-ubuntu_amd64.deb youdao-dict/DEBIAN
  4. 编辑control文件,删除Depends里面的gstreamer0.10-plugins-ugly。
  5. 重新打包
    dpkg-deb -b youdao-dict youdaobuild.deb
  6. 安装重新打包的安装包
    dpkg -i youdaobuild.deb