对‘vtable for XXX’未定义的引用
原因分析:父类中的虚函数只有声明,没有定义。
解决方案:
1.定义相关的虚函数的实现
2.定义成纯虚函数留给后代实现,virtual int broadcast(const char* pBuf, const unsigned bufSize) = 0
ifstream.good()返回0
原因之一,当前用户对文件没有相应权限
pure virtual method called
原因之一:子类已析构,调用父类的纯虚函数
Stack smashing detected
问题原因:栈溢出,如下所示,当写入head的字符串大于128字节时,就会导致此错误。
char head[128];
head[129] = 'a';
注意:当出现这个问题时,程序会继续执行;但是在函数返回时会出现错误提示,程序退出。
前置声明使用注意事项
如果类A中用到了类B,而类B的用到了类A,这时便需要用到类的前置说明 ,但需要注意的是:前置声明只能作为指针或引用,不能定义类的对象,自然也就不能调用对象中的方法了。
解决方案:
将类的声明和类的实现(即类的定义)分离,在实现文件中引用需要的头文件。
expected identifier before numeric constant
枚举类型和宏重名
C++模板声明与定义分离,导致未定义的错误
问题现象
传统编程方法(在*.h文件声明,在*.cpp文件中定义)用于模板,编译时会出现未定义的错误。
原因分析
C++编译以源文件为单位,每一个对象所占用的空间大小,是在编译的时候就确定的。而模板当然不是数据类型,模板就是模板,模板有个具现化的过程,在模板类被使用的之前,编译器无法知道模板类对象的大小,因而不会生成二进制文件。
//test.h
template <class T>
void test(T a);
//test.cpp
#include”test.h”
template <class T>
void test(T a)
{
//do something
}
//main.cpp
#include”test.h”
int main()
{
test(1);
}
编译main.cpp时,对test的调用会展开模板的具现化,但是编译器在test.h文件中只看到了模板的声明,没有模板的定义,因此编译器不能创建类型test(int)
, 不过这时并不报错,编译器认为模板定义在其它文件中,就把问题留给链接程序处理。
编译器编译test.cpp时也不会生成函数的二进制代码,因为要生成代码,需要知道模板参数,即需要一个类型,而不是模板本身。因此当链接器去链接main.obj和test.obj时就会报出未定义的错误。
模板声明与定义正确分开方法
了解了问题本质,就清楚了解决问题的方法:在模板具现化时让编译器看到模板定义。
//test.h
template<class T>
class A
{
public:
void test(T a); //这里只是个声明
};
#include<test_impl.h>
//test_impl.h
template<class T>
void A<T>::test(T a)
{
//do something
}
//main.cpp
#include”test.h”
int main()
{
A<int> a;
a.test(1);
}