学习中对c++的记录

1.在指针里,const的使用方法有三种,他们代表的意义也不同。
一种是这样的,const type *name=…;它的意义是,定义了一个常量指针,常量指针就是指针里面的值(就是地址)是不能被改变的。
还有一种是这样的,type const *name;它的意义是,定义了一个变量指针,但是他是指向一个常量的地址的。
还有一种更加丧心病狂的,const type const *name=…;它的意义是,定义了一个常量指针,指针指向一个常量。

  1. 3 与 5; 位与运算: 同为1 则为1 其他为0; 3的2进制为 011; 5的2进制为 101; 只有最低位为1; 所以值为 001 也就是1了;

  2. 引用类型–
    #include
    #include<stdio.h>
    using namespace std; //传地址方式 - 引用类型做参数
    void swap_yinyong(int &m, int &n){
    int t;
    t = m;
    m = n;
    n = t;
    }

4.指针–
int (*p)[3]:定义了一个名为p的指针变量,该指针指向一个三元素数组,p是一个指针变量,可以重新赋值;

example:
int a[3]={1,2,3},(*p)[3];
p=&a;
编译会通过,因为p是一个指针变量,可以再赋值
int *p[3]:定义了一个名为p的数组,该数组有三个元素,每个元素都是一个指针,指针指向整形变量;

5.形式参数是额外分配的内存;

6.传对象(传值)
主程序调用函数的实际参数时系统会将实际参数的数值传递并复制给函数中相对应的形式参数
从定义中标红的字可以看出,函数内的形式参数执行完毕后不会修改主程序中调用时变量自身的内容;

  1. 传对象指针(传址)
    在调用函数时系统并没有分配实际的地址给函数的形式参数,而是将实际参数的地址直接传递给对应的形式参数
    换句话说C++是以分配指针变量的形式参数来存放实际参数所传入的变量地址
    8.传引用
    类似于传址调用的一种,但是在传引用方式的函数中形式参数并不会另外分配内存来存放实际参数传入的地址,而是直接把形式参数作为实际参数的一个别名

  2. 默认形参 在函数定义阶段,就已经被赋值了。
    def func(x,y=10):
    特点: 在函数定义阶段就已经被赋值,意味着在调用时可以不用为其再次赋值了。
    注意注意注意!!!:
    1、位置形参必须放在默认形参的左边。
    2、默认形参的值只在定义阶段赋值一次,也就是说默认参数的值 在函数定义阶段就已经固定了。
    案例如下: m=15
    def foo(x=m):
    print(x)
    m=200
    oo()
    打印结果是:15不是200,充分说明了: 默认参数在函数定义阶段就已经固定了, 即使在函数执行阶段,默认形参的值也不会发生改变。

10.函数
构造函数:

  1. 函数名与类型相同
  2. 不能定义返回值类型也不能有return 语句
  3. 可以有形式参数也可以没有形式参数
  4. 可以是内联函数
  5. 可以重载
  6. 可以带参数值
  7. 先构造的对象,后析构
    析构函数
    对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用。
    若new一个对象数组,那么用delete释放时应该写 []。否则只delete一个对 象(调用一次析构函数)
    析构函数在对象作为函数返回值返回后被调用:
  1. 一、函数模板通式
    1、函数模板的格式:
    template <class 形参名,class 形参名,…> 返回类型 函数名(参数列表)
    {
    函数体
    }
    其中template和class是关见字,class可以用typename 关见字代替,在这里typename 和class没区别,<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。一但声明了模板函数就可以用模板函数的形参名声明类中的成员变量和成员函数,即可以在该函数中使用内置类型的地方都可以使用模板形参名。模板形参需要调用该模板函数时提供的模板实参来初始化模板形参,一旦编译器确定了实际的模板实参类型就称他实例化了函数模板的一个实例。比如swap的模板函数形式为:
    template void swap(T& a, T& b){},
    当调用这样的模板函数时类型T就会被被调用时的类型所代替,比如swap(a,b)其中a和b是int 型,这时模板函数swap中的形参T就会被int 所代替,模板函数就变为swap(int &a, int &b)。而当swap(c,d)其中c和d是double类型时,模板函数会被替换为swap(double &a, double &b),这样就实现了函数的实现与类型无关的代码。
    2、注意:对于函数模板而言不存在 h(int,int) 这样的调用,不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用实参推演来进行,

3.即只能进行 h(2,3) 这样的调用,或者int a, b; h(a,b)。
一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。比如
template class A
{
public: T a; T b; T hy(T c, T &d);
};
在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。

  1. 关于new 和 delete

student *p = new student; //分配一个新的内存空间
P -> name = “wang”;
delete p; //不需要的内存块要及时释放
p = new student[3];
p[1].score = 67;
*p(+1).score = 67;
P -> score = 78;

使用new创建对象时,若类有默认的构造函数或没有构造函数,则不需要初始化值;若类只有含参的构造函数,则需要初始化值。

若new一个对象数组,那么用delete释放时应该写[],否则只delete一个对象(调用一次析构函数)。
  1. 在类内定义函数叫做函数的声明;
    在类外定义的成员函数叫做函数的实现;
    其中: 在类体外定义的成员函数必须加类作用域;
    Eg: class student
    {
    };
    Void student::print(){ };

  2. struct 和 class 的区别:
    Struct 里的成员默认为公有成员;
    Class 里的成员默认为私有成员;
    Eg: class sudent{
    String name;
    }
    Int main()
    {
    Student stu;
    Stu.name = zhou; // 这样不成立 因为class里的 name现在为私有成员不可以调用

  3. 内联函数:
    内联函数的原理是编译器(编译时)将使用相应的函数代码替换函数调用。因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。

  4. 派生类:
    1、派生类的对象可以赋值给基类对象;
    2、派生类的对象可以初始化基类的引用;
    3、派生类对象的地址可以赋给指向基类的指针。
    在替代之后,派生类对象就可以作为基类的对象使用,但是只能使用从基类继权承的成员。
    类型兼容规则是多态性的重要基础之一。

  5. 复制构造函数被调用的三种情况(csdn收藏)
    其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。

18.继承方式
所谓继承方式,包括对基类属性和方法两个方面的继承。体现在访问权限上的不同(public、private、protected)。
Public
 基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。
 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
 通过派生类的对象只能访问基类的public成员。

Private
 基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。
 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
 通过派生类的对象不能直接访问基类中的任何成员。

protected
 基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可直接访问。
 派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
 通过派生类的对象不能直接访问基类中的任何成员
19.静态数据成员

  1. 静态数据成员不能用参数初始化表对静态数据成员初始化。
  2. 静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,至程序结束时才释放空间。
  3. 静态数据成员可以初始化,但只能在类体外进行初始化。
  4. 静态数据成员不能用参数初始化表对静态数据成员初始化
    如: class Box
    {
    public:
    int volume();
    private:
    static int height;
    int width;
    int length
    };
    int Box::height = 10; //正确
    Box(int h, int w, int len):height(h){} //错误
  1. 静态成员函数

静态成员函数:普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。
因此静态成员不需要通过对象就能访问
如何访问静态成员
class CRectangle
{
private:
int w, h;
static int nTotalArea; // 静态成员变量
static int nTotalNumber;
public:
CRectangle(int w_,int h_);
~CRectangle();
static void PrintTotal(); // 静态成员函数
};

  1. 类名::成员名
    CRectangle::PrintTotal();
  2. 对象名.成员名
    CRectangle r;
    r.PrintTotal();//但是PrintTotal函数并不是作用在r这个对象上
  3. 指针->成员名
    CRectangle * p = &r;
    p->PrintTotal();//但是PrintTotal函数并不是作用在p这个对象上
  4. 引用.成员名
    CRectangle & ref = r;
    int n = ref.nTotalNumber;//nTotalNumber不是属于ref这个对象的,是属于CRectangle这个类的

静态成员函数不传递this指针。
注:也就是说静态成员函数不接受隐含的this指针,无法直接访问类中的非静态成员。

21.把const的地址赋值给非const 指针变量,是不行的。
把const的地址赋值给const 指针变量,是可行的。
把非const的地址赋值给const 指针变量,是可行的。

22.于string的用法 csdn 中 c++ 收藏。

  1. this指针
  1. This的作用域是在类内部,只能在成员函数中使用。
  2. this 指针是一个系统预定义的特殊指针,指向当前正在操作的对象。
  3. const成员函数内部可以使用this 指针
  1. 【C++】子对象基础概念及其用法 (CSDN)
    一、什么是子对象
    当一个类的成员是某一个对象的类时,该对象就是子对象,驻留在另一个对象中的对象,在一个类的定义中,声明另一个类的对象来作为成员变量。
    二、子对象的作用是什么
    减少代码重用
    当一个类中出现了另一个类的对象成员时,该类的构造函数就要包含子对象的初始化(成员初始化列表放在构造函数的右边),并用冒号进行分隔。成员初始化列表是由一个或多个选项组成的,多各选项之间用逗号分隔

25.关于访问
规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问

公有继承时,水平访问和垂直访问对基类中的公有成员不受限制;
私有继承时,水平访问和垂直访问对基类中的公有成员也不能访问;
保护继承时,对于垂直访问同于公有继承,对于水平访问同于私有继承。

对于基类中的私有成员,只能被基类中的成员函数和友元函数所访问,不能被其他的函数访问。

  1. vector 的用法 (CSDN)(客观查阅,部分内容不正确)

27.虚函数
虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
虚函数的使用方法是:

  1. 在基类用virtual声明成员函数为虚函数。
    这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用。在类外定义虚函数时,不必再加virtual。
  2. 在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。
    C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在每一层声明该函数时都加virtual,使程序更加清晰。如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。
  3. 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。
  4. 通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。
    通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同类的同名函数,只要先用基类指针指向即可。如果指针不断地指向同一类族中不同类的对象,就能不断地调用这些对象中的同名函数。这就如同前面说的,不断地告诉出租车司机要去的目的地,然后司机把你送到你要去的地方。
  5. 运算符重载的注意事项
  6. C++不允许定义新的运算符 ;
  7. 重载后运算符的含义应该符合日常习惯
  8. 运算符重载不改变运算符的优先级;
  9. 以下运算符不能被重载:“.”、“.*”、“::”、“?:”、sizeof;
  10. 重载运算符()、[]、->或者赋值运算符=时,运算符重载函数必须声明为类的成员函数。

运算符重载时要遵循以下规则:

( 1 ) 除了类属关系运算符 " . " 、成员指针运算符 " .* " 、作用域运算符 " :: " 、sizeof运算符和三目运算符 " ?: " 以外,C ++ 中的所有运算符都可以重载。
( 2 ) 重载运算符限制在C ++ 语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
( 3 ) 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
( 4 ) 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
( 5 ) 运算符重载不能改变该运算符用于内部类型对象的含义。它只能和用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用时。
( 6 ) 运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符。

29.关于引用(再)

  1. 什么是“引用”?申明和使用“引用”要注意哪些问题?
    答:引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。

  2. 将“引用”作为函数参数有哪些特点?
    (1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
    (2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
    (3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。

  3. 在什么时候需要使用“常引用”? 
    如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标识符 &引用名=目标变量名;

函数参数列表中的 *arr 是可以写成 int arr[] 的。

在函数声明的参数列表中声明的数组参数,是会被视作指针的,所以你写成数组或指针都一样。

但另外,声明在参数列表中的数组还可以加上其他修饰符,如static const restrict,它们对传参会有更多的影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值