10 programming mistakes that beginners in C++ make

Click " C language and CPP programming " above, select " Follow/ Top/Star

公众号”干货福利,第一时间送达!

Source: https://blog.csdn.net/chenlycly

The company has a certain turnover of personnel every year, and accordingly, some fresh students will be recruited to supplement it. Guiding fresh students has become a compulsory course for old employees. On weekdays, we will often help newcomers to troubleshoot problems in the code. In the process, we found some programming mistakes that C++ novices are prone to make. Here is a brief summary to provide a reference for newcomers.

1. Some keywords are written more in the cpp file

For C++ classes, some keywords just need to be written in .h, no need to add them in cpp, such as virtual, static and other keywords, if you write more in cpp, the compiler will report an error. For example, the definition of the following virtual interface and static member variable, as long as it is declared in the header file.

class shape
{
    virtual Draw();
    //...
    static int nLevel;
}

2. The default value of the function parameter is written into the function implementation

For functions with parameter default values, the default value is added at the function declaration, and the parameters at the function implementation do not need to be added. For the convenience of viewing the code, the default value is annotated in the parameters at the function implementation. The right thing to do is, there are default values ​​in the header file:

BOOL CreateConf( const CString& strConfName, const BOOL bAudio = FALSE );
在函数实现处的参数中不用添加默认值:
BOOL CreateConf( const CString& strConfName, const BOOL bAudio/* = FALSE*/ );
{
    // ......
}

3. When writing a class, forget to add a ";" semicolon at the end of the class

If you forget to add a semicolon at the end of the class, the compilation will report an error, and newcomers may search for a long time without finding the cause of the compilation error. It's actually very simple, forgot to add a semicolon at the end of the class.

class Shape
{
    // ...
};

4. Only function declarations are added, no function implementations

When adding a function of a class, only the function declaration is added in the header file of the class, but the implementation of the function is not added in cpp. If this function is called elsewhere, unresolved external symbolan error will be reported when compiling and linking. Because there is no implementation, there are no obj files available for linking.

5. The cpp file is forgotten to be added to the project, resulting in no obj file generated for linking

When adding C++ classes, we typically add .h header files and a .cpp source file. As a result, I forgot to add the .cpp file to the project, that is, I did not participate in the compilation and did not generate an obj file for linking. unresolved external symbolIf there is code that calls the interface of the C++ class, an error will be reported when compiling and linking , that is, the interface corresponding to the C++ class cannot be linked.

6. The function returns the address or reference of a local variable

In the function, the address or reference of a local variable is returned, and the life cycle of this local variable ends when the function ends, and the memory is released. When the memory of the variable is accessed externally, a memory access violation exception will be triggered, because the memory of the variable has been freed. For example the following error code:

char* GetResult()
{
    char chResult[100] = { 0 };

    // ......

    return chResult;
}

7. Forgetting to declare the virtual function of the interface in the parent class, resulting in polymorphism not taking effect

The code originally had to call the interface implemented by the subclass with the help of the C++ polymorphic virtual function call. As a result, I forgot to declare the corresponding interface as virtual in the parent class, resulting in no call to the function implemented by the subclass. It must be remembered that to implement polymorphic function calls, the relevant interface of the parent class must be declared virtual.

class Shape()
{
    // ...

    virtual void Draw();

    // ...
}

8. Where double pointers should be used, single pointers are used

Sometimes we need to call an interface to get some data. The interface copies the data to the memory corresponding to the passed in parameters. In this case, pointers or references are passed in when designing parameters. We define the structure pointer p before calling GetData, and new out the corresponding structure object memory. We should use double pointers (pointers of pointers) when defining the GetData interface, and the result is wrongly written as a single pointer.

The code in question is as follows:

struct CodecInfo     // 编码信息
{
    int nFrameRate;

    // ...
}


CodecInfo* pInfo = new CodecInfo;

GetAudioCodecPtr()->GetCodecInfo(pInfo);   // 调用AudioCodec::GetCodecInfo获取编码信息


AudioCodec::GetCodecInfo( CodecInfo* pInfo)  // 此处的参数不应该使用单指针
{
    memcpy(pInfo, m_codecInfo, sizeof(CodecInfo));
}

The parameters of the interface above AudioCodec::GetCodecInfoshould not be a single pointer, but a double pointer. The modified code should be as follows:

AudioCodec::GetCodecInfo( CodecInfo** pInfo)  // 此处的参数类型使用双指针
{
    memcpy(*pInfo, m_codecInfo, sizeof(CodecInfo));
}

9. When publishing the exe program, forget to bring the C runtime library and MFC library that the exe depends on

For example, a newcomer uses the VS-MFC library to write a tool software for testing. As a result, when the release version program is released, the C runtime library that the program depends on is not brought with it, which causes the tool software to start up in some computers and report an error, indicating that it cannot be found. to the C runtime library:

Because the program depends on the dynamic version of the runtime library and the MFC library, you should bring these libraries with you when you publish the program. Some systems do not have these libraries, and when the program starts, it will report that the library cannot be found, and the startup will fail.

10. You should use a deep copy, but use a shallow copy

It should have been deep copied, but shallow copy (direct assignment) was used, resulting in another C++ object with a different life cycle pointing to the same piece of memory. After one object releases the memory, another object uses this memory again. It causes a memory access violation and an exception occurs.

There is a classic C++ written test question, let us implement the related functions of the String class, the main purpose of which is to examine the understanding of deep copy and shallow copy. The declaration of the String class is given in the title:

class String{
public:
    String();
    String(const String & str);
    String(const char* str);
    String& operator=(String str);
    char* c_str() const;
    ~String();
    int size() const;
private:
    char* data;
};

Let's write the internal implementation of the above functions. The implementation code of these functions is as follows:

//普通构造函数  
String::String(const char *str)
{
  if (str == NULL)
  {
    m_data = new char[1];// 得分点:对空字符串自动申请存放结束标志'\0'的,加分点:对m_data加NULL判断  
    *m_data = '\0';
  }
  else
  {
    int length = strlen(str);
    m_data = new char[length + 1];// 若能加 NULL 判断则更好
    strcpy(m_data, str);
  }
}
 
 
// String的析构函数  
String::~String(void)
{
  delete[] m_data; // 或delete m_data;  
}
 
 
//拷贝构造函数  
String::String(const String &other)// 得分点:输入参数为const型  
{     
  int length = strlen(other.m_data);
  m_data = new char[length + 1];// 若能加 NULL 判断则更好  
  strcpy(m_data, other.m_data);
}
 
 
//赋值函数  
String & String::operator = (const String &other) // 得分点:输入参数为const型  
{
  if (this == &other)//得分点:检查自赋值  
    return *this; 
  if (m_data)
      delete[] m_data;//得分点:释放原有的内存资源  
  int length = strlen(other.m_data);
  m_data = new char[length + 1];//加分点:对m_data加NULL判断  
  strcpy(m_data, other.m_data);
  return *this;//得分点:返回本对象的引用    
}

Simple sharing and happy learning, please forgive me if there are any mistakes!

PS: Welcome to share, like, and watch.

Guess you like

Origin blog.csdn.net/weixin_41055260/article/details/123887786