Essential C++ 面向过程的编程风格


前言

本文为读书笔记,记录在Essential C++ 中学习的编程规范和注意事项。


1.Reference的使用

当我们以by reference 方式将对象作为函数参数传入时,复制的是对象的地址。对传入的对象进行简介操作。
将参数声明为reference的作用:

  1. 直接对所传入的对象进行修改。
    冒泡排序 void bubble_sort(vector vec) 参数用传值的方式无法得到正确的排序结果;使用传址的方式才正确。
  2. 降低复制大型对象的额外负担。

Pointer 与 Reference传递的效果相同,但它可能不指向某个实际对象,所以需要判别指针是否为空。

2.动态内存管理

Local scope 或 file scope 由系统自动管理。第三种储存期形式称为 dynamic extent,内存由程序的空闲空间分配而来,也称为heap memory(堆内存)。这种内存必须由程序员自行管理,分配通过new表达式来完成,释放则通过delete。

  • pi = new int(1024); 分配出一个类型为int的对象
  • int *pia = new int [24] ; 由heap分配出一个数组,数组大小为24

3.使用模板函数

template <typename elemType>
void display_message(const string &msg,const vector<elemType> &vec)
{  
     cout << msg;
     for(int ix = 0; ix < vec.size(); ++ix){
         elemType t = vec[ix];
         cout << t << ' ';
     }
}

模板函数以关键字template开场,其后是用尖括号围起来的一个或多个标识符;这些标识符用以表示我们希望推迟决定的数据类型。
使用模板函数的方法:

vector<int> ivec;
string msg;
// ...
display_message( msg, ivec );

4.使用函数指针

指向函数的指针,函数指针的定义方式:

data_types (*func_pointer)( data_types arg1, data_types arg2, ...,data_types argn);

例如,int(* fp)(int a); 定义了一个指向函数(函数返回值类型为int,参数类型为一个int)的指针。
函数指针的使用方法:

int test(int a)
{
    return a;
}
int main(int argc, const char * argv[])
{
    
    int (*fp)(int a);
    fp = test;
    cout<<fp(2)<<endl;
    return 0;
}

参考文章:https://blog.csdn.net/crayondeng/article/details/16868351

指向类成员函数的函数指针:

  1. 函数指针赋值需要使用&;
  2. 使用 .* 或 ->* 调用类成员函数指针所指向的函数;

举例说明:

//指向类成员函数的函数指针
#include <iostream>
#include <cstdio>
using namespace std;
 
class A
{
	public:
		A(int aa = 0):a(aa){}
 
		~A(){}
 
		void setA(int aa = 1)
		{
			a = aa;
		}
		
		virtual void print()
		{
			cout << "A: " << a << endl;
		}
 
		virtual void printa()
		{
			cout << "A1: " << a << endl;
		}
	private:
		int a;
};
 
class B:public A
{
	public:
		B():A(), b(0){}
		
		B(int aa, int bb):A(aa), b(bb){}
 
		~B(){}
 
		virtual void print()
		{
			A::print();
			cout << "B: " << b << endl;
		}
 
		virtual void printa()
		{
			A::printa();
			cout << "B: " << b << endl;
		}
	private:
		int b;
};
 
int main(void)
{
	A a;
	B b;
	void (A::*ptr)(int) = &A::setA;
	A* pa = &a;
	
	//对于非虚函数,返回其在内存的真实地址
	printf("A::set(): %p\n", &A::setA);
	//对于虚函数, 返回其在虚函数表的偏移位置
	printf("B::print(): %p\n", &A::print);
	printf("B::print(): %p\n", &A::printa);
 
	a.print();
 
	a.setA(10);
 
	a.print();
 
	a.setA(100);
 
	a.print();
	//对于指向类成员函数的函数指针,引用时必须传入一个类对象的this指针,所以必须由类实体调用
	(pa->*ptr)(1000);
 
	a.print();
 
	(a.*ptr)(10000);
 
	a.print();
	return 0;
}

运行结果:

A::set(): 00E8103C
B::print(): 00E81348
B::print(): 00E812E9
A: 0
A: 10
A: 100
A: 1000
A: 10000
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值