编程细节

1.  双精度变量与0的比较:

    const double eps = 0.000000001;
    double         a = 0.00000000001;
    double         b = 0.000000002;

    if (a >= -eps && a <= eps)  // if(a <= -eps || a >= eps)
        cout << "a == 0" << endl;
    else
        cout << "a != 0" << endl;

    if (b >= -eps && b <= eps)
        cout << "b == 0" << endl;
    else
        cout << "b != 0" << endl;

2. 参数列表、初始化列表:

.h:
class Complex {
public:          //外部接口
    Complex(double real=0.0, double imag=0.0);
    //另外,带有默认值参数应放在列表的最右端
    //Complex(double real, double imag=0.0)
private:        //私有数据成员
    double real;  //实部
    double imag;  //虚部
}

.cpp:
  //带有默认值参数的函数,在实现的时候,参数上是不能有值的
 error: Complex::Complex(double real=0.0, double imag=0.0){...}
 //另外,只有构造函数能使用初始化列表,其在构造函数执行前执行
    Complex::Complex(double real, double imag)
        :real(real), imag(imag){}

3. 重载单目运算符(一元运算符)++ 、--:

  前置与后置的区分:(1)后置带有整型形参;

           (2)前置返回计算后的值,后置返回计算前的值。

4. 重载赋值运算符‘=’:

  (1)首先,需要进行是否是自我赋值操作的验证;

  (2)其次,要释放左操作数的资源:

      方法1 先保存原来的资源,等重新分配资源完成以后再释放以前的资源),

      方法2 采用copy and swap技术;

    (3)返回类型,为了具有连续赋值的效果,一般都返回引用类型。

5. new / delete 和 malloc / free 的区别:(参考https://blog.csdn.net/shellching/article/details/50786940

  (1)new / delete是运算符,malloc / free是函数;

  (2)无法new一个抽象类,但是可以malloc出一块抽象类的空间;

  (3)new/delete会调用构造/析构函数,malloc / free只分配/释放空间;

  (4)new内存分配失败时,会抛出bac_alloc异常,malloc分配内存失败时返回NULL;

  (5)C++允许重载new / delete操作符,而不允许重载malloc / free。

6.  关键字 explicit (明确的)的作用:(参考https://www.cnblogs.com/ymy124/p/3632634.html

  防止类构造函数的隐式自动转换

7.  关键字 volatile (易变的)的作用:(参考https://www.cnblogs.com/zhaoli/p/4250468.html

  volatile的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值;

  防止编译器对变量进行优化。

 2018-09-15

1.尽量用const、enum、inline替换 #define  (宁可 以编译器替换预处理器)

  #define  只是做替换操作,不会进行类型检测等。

  • 对于单纯变量,最好用const、enum代替#define
  • 对于形似函数的宏,最好用inline函数代替#define

2. 

.h:
class  Student{
private:
   static int   num_1;
   const  int   num_2; 
   static const int num_3 = 3; 
   enum{num_4=4};

   int arr[num_?];      // 3、4
    
};

.cpp
      int Student::num_1 = 1;
const int Student::num_2 = 2;
const int Student::num_3; //有些编译器坚持要看到定义式,在声明时已赋值,这里不能再设值

 

 

 

3. const 声明的变量

int a = 1;
const int* p = &a;  // (*p)++ 不可用  p++可用
//(不能通过指针改变变量a的值,指针指向的地址可变)
int const* p  = &a ; //同上
int* const p = &a ;  //(*p)++ 可用  p++不可用
const int* const p = &a ;//(*p)++ 可用  p++可用

 

4. 函数形参中的值传递和引用传递

 

#include <iostream>
#include <windows.h>
using namespace std;
void ssss()
{
    const int s = (unsigned int)(-1) >> 5;
    int i = s;
    while(i)i--;
}

int func1(int a)  // not change n
{
    //ssss();
    a = 1;
}

int func2(int &a) // changed n
{
    //ssss();
    a = 2;
}

void func3(int* p) // changed n
{
    //ssss();
    int a = 3;
    *p = a;
}

void func4(int* p) // not change n and not change p
{
    //ssss();
    int a = 4;
    p = &a;
}

void func5(int* &p) // not change n but it will change p
{
    //ssss();
    int a = 5;
    p = &a;

    //the p point to a temporary variable(临时变量),
    //when this func over,the temporary variable will be released,
    //so the (*p) maybe not is a's value
}

int main(void)
{
    DWORD ts,te;
    ts = GetTickCount();
    int n = 0;
    int *p = &n;
    cout << n <<endl;
    cout << ">>>>>>>>>>>>>>->->>>>"<<endl;
    ts = GetTickCount();
    func1(n);
    te = GetTickCount();

    cout << "func1: using time: "<< (te-ts)*1.0/100000 <<"\n";
    cout << n <<endl;


    ts = GetTickCount();
    func2(n);
    te = GetTickCount();
    cout << "func2: using time: "<< (te-ts)*1.0/100000 <<"\n";
    cout << n <<endl;

    ts = GetTickCount();
    func3(p);
    te = GetTickCount();
    cout << "func3: using time: "<< (te-ts)*1.0/100000 <<"\n";
    cout <<  "n: " << n <<endl;

    cout << "*p: " << (*p) <<endl;

    p = &n;

    cout << " before. p: " << p << endl;
    ts = GetTickCount();
    func4(p);
    te = GetTickCount();
    cout << " after. p: " << p << endl;
    cout << "func4: using time: "<< (te-ts)*1.0/100000 <<"\n";
    cout << "n: " << n <<endl;

    cout << "*p: " << (*p) <<endl;

    p = &n;

    cout << " before. p: " << p << endl;
    ts = GetTickCount();
    func5(p);
    te = GetTickCount();
    cout << " after. p: " << p << endl;
    cout << "func5: using time: "<< (te-ts)*1.0/100000 <<"\n";
    cout << "n: " << n <<endl;

    cout << "*p: " << (*p) <<endl;

    return 0;
}

5. 基类的析构函数最好都为虚析构函数

  当定义有基类指针且指向派生类的对象时,基类的析构函数若不是虚析构函数将会造成内存的泄露。

 2018-09-18

posted on 2018-09-15 20:21 lMimjx 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值