[TOC]

文章参考:https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/

概述

SonarLint代码

问题:Polymorphic base class destructor should be either public virtual or protected non-virtual

多态基类析构函数应该是 public virtual 或 protected non-virtual

当没有virtual析构函数的类用作基类时,如果使用指向此类实例的指针,则会发生意外。具体来说,如果派生类的实例是delete通过指向基类型的指针来创建的,则行为是未定义的,并且可能导致资源泄漏、崩溃或内存损坏。

如果不希望删除基类指针,则应使析构函数protected避免这种误用。

不合规代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
class Base { // Noncompliant: no destructor is supplied, and the default version is not virtual
public:
Base() {}
virtual void doSomething() {}
};

class Derived : public Base {
}

void f() {
Base *p = new Derived();
delete p; // Undefined behavior
}

合规解决方案

1
2
3
4
5
6
class Base {
public:
Base() {}
virtual ~Base() = default;
virtual void doSomething() {}
};

问题:Member data should be initialized in-class or in a constructor initialization list

成员数据应在类内或构造函数初始化列表中初始化

问题:C-style array should not be used

C风格的数组(比如int i[10])使用起来不是很方便:

  • 它们是固定大小的(甚至 C VLA 也不是真正可变大小的,并且它们在 C++ 中不受支持)
  • 如果数组中的元素个数可以变化,就会导致手动分配内存(或者人们会使用“应该足够大”的固定大小的数组,这既是内存的浪费,也是程序的局限性)
  • 很容易丢失数组的大小,因为传递给函数的数组会衰减为指针

不合规代码示例

1
2
3
void f() { 
int a[10]; // 不合规
}

合规解决方案

1
2
3
4
5
6
7
void f() { 
std::array<int, 10> a1; // 如果大小真的是一个常量
// 或者
std::vector<int>a2; // 对于可变大小

auto s = "Hello!"; // 异常兼容
}

此规则不会报告在extern "C"代码中使用 C 样式数组(因为此处通常需要这些数组以与外部代码兼容)和main.

问题:No viable overloaded operator[] for type ‘const std::map<int,Obj*>’

文章参考:https://www.jianshu.com/p/d484c01ccb1b

方法里面使用map[]符号报错,但是在别的方法里面同样的用法没问题

报错原因是由于方法后面加了const修饰导致的。
具体我们可以进到map的头文件中得知一二。