问题一
在使用继承时,遇到下面的问题
error: ‘void BaseServer::StartServer(BaseServer*)’ is inaccessible
void StartServer(BaseServer *m_bserver);
即父类无法调入子类参数,原因竟是继承时忘记加public导致私有继承
问题二
在c中常常使用一个总头文件来定义全局变量,如果只在总头文件中声明,然后在其他头文件中include ,使用时会出现多次定义的错误。至少应该在.c中定义初始化,在头文件中使用extern。或者通过类的实例,类与类之间的关系来访问。
问题三
在linux下创建线程时,创建线程的函数与c++的语法冲突(c++相对于c语法更加严格一些)
pthread_create(&pthread_id, NULL, ServerThread, NULL)
(error: invalid conversion from ‘void*’ to ‘void* ()(void)’)
解决办法,将线程函数设置为c,不在类中定义。即ServerThread设置为c函数,声明时加
#ifdef __cplusplus
extern "C" {
#endif
static void *ServerThread(void *);
#ifdef __cplusplus
}
#endif
//(void *)也必须添加
问题四
关于静态变量的声明和定义。静态成员属于全局变量,是所有实例化以后的对象所共享的,而成员的初始化可以想象成向系统申请内存存储数据的过程,显然这种共有对象不能在任何函数和局部作用域中初始化。也不能在.h中初始化,必须在.cpp中初始化。
//.h
class BaseServer
{
private:
static int connfd; //declaration static variable and define in .cpp file
static bool isConnected;
}
//.cpp
int BaseServer::connfd = 0;
bool BaseServer::isConnected = 0;
qt中浮点数转换为字符串时,如果使用QString("%1").arg(data)该种方法,得出的字符串位数很少,影响显示数值的精度。另外一种方法是
QString QString::number(double n, char format = ‘g’, int precision = 6) [static]
Returns a string equivalent of the number n, formatted according to the specified format and precision. See Argument Formats for details.
Unlike QLocale::toString(), this function does not honor the user’s locale settings.
QString::number(data,'g',10);//10代表10个字符
问题五
定义了类指针而不new,坑了一天!
问题六
assert 函数: assert 是个宏, 这个宏检查传给它的表达式是否非零, 如果不是非零值, 就会发出一条出错信息并调用 abort. assert 只是在没定义标准宏NDEBUG 的时候, 即在调试状态下才这么做。在产品发布状态下, 即定义了NDEBUG 的时候, assert 什么也不做, 相当于一条空语句。所以你只能在调试时才能检查断言
问题七
回调函数: 系统每次调用该函数时,如果函数中定义有变量并赋有初值,那么每次调用这些变量,其值都将被重置。这点务必重视。使用static即可解决。
静态局部变量使用说明:
在静态存储区内分配存储单元,程序整个运行期间不释放
在编译时赋初值,只赋初值一次。每次保留上次函数调用结束时的值
若不赋初值则编译自动赋值为0(数值型变量)或空字符(字符型变量)
在其他函数中不可见
用完该值后尽快复位,以免引起不必要的逻辑错误
问题八
隐式转换: 务必注意
#include <stdio.h>
void test(float a)
{
printf("%f\n",a);
}
int main()
{
int i=10;
test((float)i/100);//0.100000
test(i/100);//0.000000
test(i/100.0f);//0.100000
return 0;
}
//两次test的值不一样!!!!!
//printf("%.nf",&f);//n代表显示浮点数时,小数点后显示几位
问题九
使用scanf读取文本中固定格式数据
FILE *fp = fopen("InitPos","r");
fscanf(fp,"x:%f,y:%f,yaw:%f",&fCurX,&fCurY,&fCurYaw);//这里的变量不能是double型
问题十
cannot convert from type void*(classname::) () to type void*(*)(void*)
解决方法:(参考链接)
方法一:将传入pthread_create的函数定义为static
void *Test::Func(void *)//static
{
std::cout << "hello" << std::endl;
}
void Test::CreateThread()
{
pthread_t id;
int err = pthread_create(&id,NULL,Func,NULL);
if(err != 0)
std::cout << "can't create thread" << std::endl;
}
方法二:往往Func函数有很多类的成员,因此并不想让Func函数定义为static(定义为static便无法访问类成员)
If you want to use pthreads, then you’ll need a static or non-member function for the entry point. You can pass a pointer to your object to this function, using it as a trampoline into the non-static member function:
class Test
{
public:
Test();
void* Func(void* arg);
void CreateThread();
static void* helpFunc(void* self)
{
return static_cast<Test*>(self)->Func(self);
}
};
void Test::CreateThread()
{
pthread_t id;
int err = pthread_create(&id,NULL,helpFunc,this);
if(err != 0)
std::cout << "can't create thread" << std::endl;
}
static_cast < type-id > ( expression )该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。
它主要有如下几种用法:
用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
把void指针转换成目标类型的指针(不安全!!)
把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
方法三:
void RecvCommand();
static void RecvProc(int nArgv)
{
((CRead*)nArgv)->RecvCommand();
return ;
}
m_pthread->CreateThread(CRead::RecvProc,this);
//实际上同方法二,只是这里的强制转换的方式不一样而已
问题十一
error: jump to case label,解决办法: 对象作用域的问题
————————————————
版权声明:本文为CSDN博主「北京-大白」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/robothj/article/details/80304081