0
点赞
收藏
分享

微信扫一扫

面向对象课笔记

引用

定义引用时一定要将其初始化成引用某个变量 ​​int &b;//error​​​ 初始化后,他就一直引用该变量,不会再引用别的变量了
对变量声明一个引用,编译系统不给它单独分配存储单元,i和j都代表同一变量单元

常引用:不能通过常引用去修改其引用的内容
​​​const int &n = a;​​​​n = 1; //error​

T & 类型的引用或者T类型的变量可以用来初始化const T & 类型的引用
const T 类型的常变量和const T & 类型的引用不能用来初始化T & 类型的引用,除非进行强制类型转换

指针引用
​​​int a = 10;​​​​int *p = &a;​​//p是一个指针,指向a的地址
​int *&q = p;​​//q是一个指针引用,是指针p的引用
此时​​&a = p = q​

const

常指针:不可通过常指针修改其指向的内容
​​​int n, m;​​​​const int *p = &n;​​​​*p = 5;//error​​​​p = &m;//ok​

不能把常指针赋值给非常指针,反过来可以。
或者强制转换将常指针赋值给非常指针:int *q=(int *)p;//ok

(1)指向常量的指针(常量指针)
const char *p = “hello”;
const 修饰char *p指向的值,"hello"不可改变
p只是一个指针,可以修改p。p = “world”;//ok

(2)常指针(指针常量)
char * const p = “hello”;
声明一个名为p的指针变量,该指针是指向字符型数据的常指针,用"hello"地址初始化该常指针

(3)指向常量的常指针
const char* const p = “hello”;
声明一个名为p的指针变量,是一个指向字符常量的常指针

注意在C语言中,const int a=1;可以通过int *b=&a,*b=2;的方式修改a
但是在C++中,会发生编译错误。在C++中,不能通过常量指针(指向常量的指针),去修改其指向的变量

内联函数

在函数定义前面加inline关键字,即可定义内联函数。注意递归函数不可以定义内联函数

函数重载

一个或多个函数,名字相同而参数个数或参数类型不同,这个叫函数的重载

函数的缺省参数

定义函数时可以让最右边的连续若干个参数有缺省值,那么调用函数的时候,若相应位置不写,则为默认值。
注意函数调用时,如果一个参数使用默认值,其右面的值都必须采用默认值

动态内存分配

new T; new T[n] //返回的类型都是T*类型
delete p; delete []p; //p必须是被new出来的空间
注意不可对同一内存delete两次

new二维数组mxn

int **a = new int *[m];
for (int i=0; i<m; i++)
a[i] = new int[n];

构造函数、初始化列表

构造函数特点:自动调用,与类同名,没有返回值

class Test{
public:
int a;
Test(int n){a = n;}
}
Test *array[2] = {new Test(2), NULL};

此时array[0]被分配一个Test对象,而array[1]只是一个指针

数据成员是按照他们在类中声明的顺序进行初始化,与他们在初始化列表中列出的顺序无关

复制(拷贝)构造函数

注意拷贝构造函数本质上是构造函数,只有对象初始化时才会调用

只有一个参数,即对同类对象的引用
X::X(X &) 或X::X(const X &)

赋值构造函数起作用的三种情况
1、当用一个对象去初始化同类的另一个对象时
Complex c2(c1);
Complex c2 = c1; //初始化语句,非赋值语句,所以也会调用拷贝构造函数

2、如果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用

3、如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用

类型转换构造函数(构造函数的一个特例)

转换构造函数的目的是实现类型的自动转换
只有一个参数,而不是复制构造函数,一般可以看成类型转换构造函数

当需要的时候,编译系统会自动调用转换构造函数,建立一个无名的临时对象(或临时变量)

class Complex{
public:
double x;
Complex(int i){
x = i;
}
};
Complex c1(1); //转换构造函数本质是构造函数
c1 = 2; //2被自动转换成一个临时Complex对象

当转换构造函数执行后,赋值给一个已经被初始化的对象后,该匿名对象将被析构

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

class Test {
public :
int x;
Test(int t) { this->x = t; cout << "转换构造"<<x<<endl; }
~Test() { cout << "析构"<<x<<endl; }
};
int main() {
Test t1(1);
Test t2 = 2;
t2 = 3;
system("pause");
return 0;
}
执行结果
转换构造1
转换构造2
转换构造3
析构3
析构3
析构1

析构函数

当在函数体内return一个对象类型是,会自动调用拷贝构造函数生成一个匿名对象。
当返回给接收的对象时,如果此对象已经被初始化,则这个匿名对象会被析构掉,否则直接转换给这个对象。相当于​​​Test t=Test(2);​

#include <iostream>
using namespace std;

class Test {
public :
int x;
Test(int t) { this->x = t; cout << "转换构造"<<x<<endl; }
Test(const Test &t) {
this->x = t.x + 2;
cout << "拷贝构造" << x << endl;
}
~Test() { cout << "对象析构"<<x<<endl; }
};
Test func() {
Test t2(1);
return t2;
}
int main() {
Test t1(5);
t1 = func();
system("pause");
return 0;
}
执行结果
转换构造5
转换构造1
拷贝构造3
对象析构1
对象析构3 最后程序结束后会有一个转换构造5的析构调用


举报

相关推荐

0 条评论