欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++ 编程过程中遇到的问题积累

程序员文章站 2022-05-17 20:33:24
...
  • 问题一

    在使用继承时,遇到下面的问题

    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);
//实际上同方法二,只是这里的强制转换的方式不一样而已
相关标签: problem