fatal error LNK1120: 无法解析的外部命令 需要在多个源文件中共享变量时,可以声明一个静态变量;如果静态变量声明在cpp文件中,会自动初始化,但不利于外部访问;如果静态变量声明在.h文件中,其它源文件包含.h文件即可访问静态变量,但要记得手动初始化;只有整形const static才可以在类内部初始化;对于一个枚举enum类型,在使用时,g++并不支持的写法:Game::eGameType::eGameType_RANDOM,但vc++和C++0x是支持的。

头文件相互包含,未声明的定义#ifndef ... #define ... #endif可以防止重复包含,但头文件相互包含会还是会导致一个问题。若两个头文件相互包含,则分别包含了这两个头文件的两个CPP文件中,至少有一个CPP文件会找不到某个类或结构体的声明,因为这个声明被放在了某个函数声明的后面。解决办法是,加上对应的前置声明。如果是头文件相互包含,最好把需要的类型放在其它位置。此外,要注意的是,全局函数的实现不要放在头文件中,除非是inline这种编译时需要展开的。

单例静态变量内存泄露 单例模式中,使用new来为静态变量赋值后,如果在析构函数中delete自己是不可行的。通常,需要另一个静态函数来delete自己,但这个函数需要手动执行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Singleton
{
public:
    ~Singleton()
    {
        //if(instance)
        //{    
            //delete this;
            //instance = NULL;
     //}
    }
    
    static Singleton* getInstance()
    {
        if(instance == NULL)
        {
            instance = new Singleton;
        }
        return instance;
    }
    
    void Suicide()
    {
        delete instance;
        instance = NULL;
    }
    
private:
    Singleton(){}
    static Singleton* instance;
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
}

Singleton* Singleton::instance = NULL;

还需要显示声明一个类的拷贝构造函数,并重载=操作符,只声明不实现,从而防止默认拷贝构造函数。其次,单例模式限制其实例只能有一个,所以把构造函数设置为私有,防止外部创建。

在单线程中,实现单例模式还有一种方法,不需要手动调用释放函数,即定义一个局部静态变量。这个静态实例创建后,生命期将延续到整个程序结束。这个方法的缺点是,静态实例是动态创建的,不确定何时创建,某处新添加的访问可能导致生存期变化。要注意的是,这种方法只适用于单线程中,考虑到线程安全,还需要使用Lock加锁的办法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Singleton
{
public:
    ~Singleton(){}
    
    static Singleton& getInstance()
    {
        static Singleton instance;
        return instance;
    }    
private:
    Singleton(){}
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
}

其实,还有一个简单办法:在头文件中声明一个全局私有静态变量,用一个GetInstance()来获得该指针。然后在构造函数中,给静态变量赋值为this即可,在析构函数中设为NULL。使用全局静态变量实现单例的好处是线程安全,静态初始化执行在Main函数之前,可以确保单线程环境。

C++编译器无法捕捉到的错误 (1)变量未初始化 (2)整数除法。如果是整数和整数相除,小数部分会被丢弃。当一个操作数是负数时,一般是向0取整。 (3)= vs == (4)混用有符号和无符号数 (5)delete vs delete[] (6)表达式副作用。例如 multiply(x, ++x),运算顺序是未定义的,这是一种错误的用法。 (7)不带break的switch语句