Thinking in C++ learning(4)----- summary


1.值替代
const 和 define比有类型检查

2.指针

指向const的指针
const int* u
int const* u

const指针
int* const w;

int d=1;
const int* const x = &d;
int const* const x2 = &d;
现在,指针和对象都不能改变

3.函数和返回值
传递const值
void f1(const int i){
    i++; //illegal -- compile-time error
}

返回const值
const int g();
对于内部类型(int, char)来说,按值返回的是否是一个const,是无关紧要的,所以应该去掉
当用户处理自定义的class,按值返回常量是很重要的

传递和返回地址

4.类
只能在构造函数里进行const变量的付值
4.1 构造函数初始化列表
4.2 内部类型的“构造函数”
float pi(3.14);
4.3 const对象和成员函数
如果声明一个对象是const,这样这个整个对象就不能被修改。如果把成员函数设置成const,那么这个函数就不能修改成员变量。不

仅要在声明的时候在函数的最后加const,而且在函数的定义也要加上

class Z {
    int i;
    mutable int j;
  public:
    Z();
    void f() const;
};
Z:Z() : i(0), j(0) {}
void Z::f() const {
  //!i++; // error -- const member function
  j++;
}

volatile 在编译器认识的范围外,这个数据可以被改变

内联函数
宏的问题
任何在类中定义的函数自动地成为内联函数,但也可以在非类的函数前面加上inline关键字使之有效,必须使函数体和声明结合在一

起,否则,编译器将它作为普通函数对待。

因为类内部的内联函数节省了在外部定义成员函数的额外开销,所以我们一定想在类声明内每一处都使用内联函数。但函数较大,会使代码膨胀

访问函数(get,set)
内联函数和编译器
任何种类的循环都被认为太复杂而不扩展为内联函数。
要显式的或者隐式的取函数地址,编译器也不能执行内联

名字控制
static如何控制存储和可见性,通过c++的名字空间特征来访问名字的改进方法
static的两种含义,
1)在固定的地址上进行存储分配,也就是说对象是在一个特殊的静态数据区(static data area)上创建的,而不是每次函数调用时

在堆栈上产生的。
2)对一个特定的编译单位来说是局部的(c++仅限于类的范围)。这样,这个名字在这个单元或类之外是不可见的

静态变量即使没有初始化,编译器也会初始化为0
静态对象的析构函数在exit()时候被调用,所以析构函数内不要调用exit()

控制连接
一般情况下,在文件作用域(file scope)内的所有名字(即不被嵌套在类或者函数中的名字)对程序中的所有编译单元来说都是可见的

。这就是external linkage,例如全局变量和普通函数都有外部连接。
如果用static声明了,那就是internal linkage。只有这个文件作用域内,是可以访问的. extern 相反


名字空间
namespace NX {
    class Y {
      static int i;
    public:
      void f();
    };
    class Z;
    void func();
}

int X::Y::i = 9;

namespace NY {
using namespace NX; //Using directive
using NX:func; //Using declaration
Y y;
}


C++中的静态成员

1.定义静态数据成员的存储
class A {
    static int i;
public:
    // ...
}
之后,必须在定义文件中为静态数据成员定义存储区
int A::i = 1;
2.静态成员函数
class X {
public:
  static void f(){};
};

int main() {
  X::f();
}

静态成员函数不能访问一般的数据成员,只能访问静态数据成员,也只能调用其他的静态成员函数

静态初始化的相依性
extern int y;
int x=y+1;
在另一个文件
extern int x;
int y=x+1;

替代连接说明
extern "C" float f(int a, char b);
这样函数f在编译时期,就不会因为重载而改变函数的名字

引用和拷贝构造函数
编译器要使用拷贝构造函数通过按值传递(by value)的方式在函数中传递和返回对象

c++中的引用
引用(&)就像能自动地被编译器间接引用的常量型指针。reference 必须有初始值,一旦一个引用被初始化为指向一个对象,他就不

能改变为另一个对象的引用。

为什么不能像内置类型一样,按值传递自定义对象
要返回自定义对象,自定义对象必须作为函数参数入栈---函数调用栈框架需要, C++和C支持中断,所以如果返回的时候是放在返回

地址的下面。这样,返回值可能会被修改。(与把返回值放到全局一样)。
为什么需要拷贝构造函数
按bitwise拷贝达不到复制对象的目的。需要重入---自己写构造函数

指向成员的指针

int ObjectClass::*pointerToMember;
定义一个名字为pointerToMember的成员指针,该指针可以指向在ObjectClass类中的任一int类型的成员
int ObjectClass::*pointerToMember = &ObjectClass::a;
class Simple2 {
public:
    int f(float) const { return 1;}
};
int (Simple::*fp) (float) const;
int (Simple::*fp2) (float) const = &Simple2::f;
int main(){
    fp = &Simple2::f;
}

多态性和虚函数
为什么传递参数要用指针或者引用,而不能直接传递对象?

为什么虚函数这么好,还要用关键字指出呢?因为,它影响效率。只要基类中的方法定义为virtual,所有子类也都是virtual了
什么是纯虚函数?为什么需要纯虚函数
实现公共接口,基类成为接口
纯抽象类?
什么是对象切片?
当向上类型转换的时候,会遇到对象切片。
构造函数对vtable的处理
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值