C++学习笔记(一)

类声明中的内容包括数据和函数,分别称为数据成员和成员函数。按访问权限划分,数据成员和成员函数又可分为共有、保护和私有3种

class 类名{
    public:
        公有数据成员;
        公有成员函数;
    protected:
        保护数据成员;
        保护成员函数;
    private:
        私有数据成员;
        私有成员函数;
};

这个类和C语言中的结构体很像,这个像不是它里面的数据,而是用法,比如class Area {.......} area1,area2;Area area ;Area *area;

  • 类声明中的关键字private、protected、public可以任意顺序出现。
  • 若私有部分处于类的第一部分时,关键字private可以省略。这样,如果一个类体中没有一个访问权限关键字,则其中的数据成员和成员函数都默认为私有的。
  • 不能在类声明中给数据成员赋初值。

成员函数

普通成员函数的定义

在类的声明中只给出成员函数的原型,而成员函数的定义写在类的外部。这种成员函数在类外定义的一般形式是:

返回值类型 类名::成员函数名(参数表){函数体}
#include <iostream>
using namespace std;

class Area {
   public :
	   int ShowArea();
	   void SetLongWide (int x, int y);
   private:
	int lenth;
	int wide;
};

void Area::SetLongWide(int x, int y) {
	lenth = x;
	wide = y;
}

int Area::ShowArea() {
	return lenth * wide;
}

int main() {
	int i = 0;
	Area area;
	area.SetLongWide(3,4);
	i = area.ShowArea();
	cout << "面积:" << i << endl;
	return 0;
}

 内联函数的定义

在函数名前冠以关键字inline,该函数就被声明为内联函数。每当程序中出现对该函数的调用时,C++编译器使用函数体中的代码插入到调用该函数的语句之处,同时使用实参代替形参,以便在程序运行时不再进行函数调用。引入内联函数主要是为了消除调用函数时的系统开销,以提高运行速度。

  • 内联函数在第一次被调用之前必须进行完整的定义,否则编译器将无法知道应该插入什么代码
  • 在内联函数体内一般不能含有复杂的控制语句,如for语句和switch语句等
  • 使用内联函数是一种空间换时间的措施,若内联函数较长,较复杂且调用较为频繁时不建议使用

隐式声明:将成员函数直接定义在类的内部

#include <iostream>
using namespace std;

class Area {
   public :
	   int ShowArea() {
		   return lenth * wide;
	   }
	   void SetLongWide (int x, int y) {
		   lenth = x;
		   wide = y;
	   }
   private:
	int lenth;
	int wide;
};



int main() {
	int i = 0;
	Area area;
	area.SetLongWide(3,4);
	i = area.ShowArea();
	cout << "面积:" << i << endl;
	return 0;
}

显式声明:在类声明中只给出成员函数的原型,而将成员函数的定义放在类的外部。

#include <iostream>
using namespace std;

class Area {
   public :
	   int ShowArea();
	   void SetLongWide (int x, int y);
   private:
	int lenth;
	int wide;
};

inline void Area::SetLongWide(int x, int y) {
	lenth = x;
	wide = y;
}

inline int Area::ShowArea() {
	return lenth * wide;
}

int main() {
	int i = 0;
	Area area;
	area.SetLongWide(3,4);
	i = area.ShowArea();
	cout << "面积:" << i << endl;
	return 0;
}

在类中,使用inline定义内联函数时,必须将类的声明和内联成员函数的定义都放在同一个文件(或同一个头文件)中,否则编译时无法进行代码置换。

 构造函数

构造函数是一种特殊的成员函数,它主要用于为对象分配空间,进行初始化。构造函数的名字必须与类名相同,而不能由用户任意命名。它可以有任意类型的参数,但不能具有返回值。它不需要用户来调用,而是在建立对象时自动执行。

#include <iostream>
using namespace std;

class Area {
public:
	Area(int m, int f);
	int ShowArea();
	void SetLongWide(int x, int y);
private:
	int lenth;
	int wide;
};

Area::Area(int m, int f)
{
	lenth = m;
	wide = f;
}

//或者如下:
//Area::Area(int m, int f):lenth(m), wide(f) {
//   cout << "构造函数使用中..." << endl;
//}


void Area::SetLongWide(int x, int y) {
	lenth = x;
	wide = y;
}

int Area::ShowArea() {
	return lenth * wide;
}

int main() {
	int i = 0;
	Area area(1,2);
	area.SetLongWide(3, 4);
	i = area.ShowArea();
	cout << "面积:" << i << endl;
	return 0;
}

或者采用如下的方式:

#include <iostream>
using namespace std;

class Area {
public:
	Area(int m, int f) :lenth(m), wide(f) {}
	int ShowArea();
	void SetLongWide(int x, int y);
private:
	int lenth;
	int wide;
};


void Area::SetLongWide(int x, int y) {
	lenth = x;
	wide = y;
}

int Area::ShowArea() {
	return lenth * wide;
}

int main() {
	int i = 0;
	Area area(1,2);
	//area.SetLongWide(3, 4);
	i = area.ShowArea();
	cout << "面积:" << i << endl;
	return 0;
}

  • 构造函数的名字必须与类名相同,否则编译程序将把它当做一般的成员函数来处理。
  • 构造函数没有返回值,在定义构造函数时,是不能说明它的类型的。
  • 与普通的成员函数一样,构造函数的函数体可以写在类体内,也可写在类体外。
  • 构造函数一般声明为共有成员,但它不需要也不能像其他成员函数那样被显式地调用,它是在定义对象的同时被自动调用,而且只执行一次。
  • 构造函数可以不带参数。

析构函数

析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用于撤销对象时的一些清理任务,如释放分配给对象的内存空间等。析构函数有以下一些特点:

析构函数与构造函数名字相同,但它前面必须加一个波浪号(~)。
析构函数没有参数和返回值,也不能被重载,因此只有一个。
当撤销对象时,编译系统会自动调用析构函数。

如果没有给类定义构造函数和析构函数,则编译系统自动生成一个默认的构造函数和析构函数。

带有默认参数值的函数

  • 当进行函数调用时,编译器按从左到右的顺序将实参与形参结合,若未指定足够的实参,则编译器按顺序用函数原型中的默认值来补足所缺少的实参。
  • 在函数原型中,所有取默认值的参数都必须出现在不取默认值的参数的右边
int fun(int a, int b, int c = 111);
  • 在函数调用时,若某个参数省略,则其后的参数皆应省略而采取默认值。不允许某个参数省略后,再给其后的参数指定参数值。

函数重载

在C++中,用户可以重载函数。这意味着,在同一作用域内,只要函数参数的类型不同,或者参数的个数不同,或者二者兼而有之,两个或者两个以上的函数可以使用相同的函数名。

调用重载函数时,函数返回值类型不在参数匹配检查之列。因此,若两个函数的参数个数和类型都相同,而只有返回值类型不同,则不允许重载。

int mul(int x, int y);
double mul(int x, int y);

函数的重载与带默认值的函数一起使用时,有可能引起二义性。

void Drawcircle(int r = 0, int x = 0, int y = 0);
void Drawcircle(int r);
Drawcircle(20);

在调用函数时,如果给出的实参和形参类型不相符,C++的编译器会自动地做类型转换工作。如果转换成功,则程序继续执行,在这种情况下,有可能产生不可识别的错误。

void f_a(int x);
void f_a(long x);
f_a(20.83);

其他基础知识

作用标识符: :

如果希望在局部变量的作用域内使用同名的全局变量,可以在该变量前加上“: :”,此时: :value代表全局变量value,

new和delete运算符

C语言中使用函数malloc()free()来进行动态内存管理。C++则提供了运算符newdelete来做同样的工作,而且后者比前者性能更优越,使用更灵活方便。

指针变量名 = new 类型
    int *p;
    p = new int;
delete 指针变量名
    delete p;

下面对new和delete的使用再做一下几点说明:

用运算符new分配的空间,使用结束后应该用也只能用delete显式地释放,否则这部分空间将不能回收而变成死空间。

在使用运算符new动态分配内存时,如果没有足够的内存满足分配要求,new将返回空指针(NULL)。

使用运算符new可以为数组动态分配内存空间,这时需要在类型后面加上数组大小。

指针变量名 = new 类型名[下标表达式];
int *p = new int[10];

释放动态分配的数组存储区时,可使用delete运算符。

delete []指针变量名;
delete p;

new 可在为简单变量分配空间的同时,进行初始化

指针变量名 = new 类型名(初值);
int *p;
p = new int(99);
···
delete p;

引用reference

引用是C++对C的一个重要扩充。变量的引用就是变量的别名,因此引用又称别名

类型 &引用名 = 已定义的变量名

引用与其所代表的变量共享同一内存单元,系统并不为引用另外分配存储空间。实际上,编译系统使引用和其代表的变量具有相同的地址。

  • 不允许建立void类型的引用
  • 不能建立引用的数组
  • 不能建立引用的引用。不能建立指向引用的指针。引用本身不是一种数据类型,所以没有引用的引用,也没有引用的指针。
  • 可以将引用的地址赋值给一个指针,此时指针指向的是原来的变量。
  • 可以用const对引用加以限定,不允许改变该引用的值,但是它不阻止引用所代表的变量的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值