c++学习点滴2

一、函数指针

func.h:

#ifndef FUNC_H_
#define FUNC_H_

#include <string>
#include <iostream>

int compare(const std::string& s1, const std::string& s2); // 普通函数

typedef int (*COMP)(const std::string& s1, const std::string& s2);

void myfun(std::string *s1, std::string *s2, COMP comp=compare); // 参数中含有函数指针,可以有默认值

#endif

func.cpp:

#include "func.h"
#include <string>
#include <iostream>

int compare(const std::string& s1, const std::string& s2) {
	return s1.compare(s2);
}

void myfun(std::string *s1, std::string *s2, COMP comp) {
	std::cout << "myfun:comp('" << *s1 << "','" << *s2 << "'): " << comp(*s1, *s2) << std::endl;
}
main.cpp:

#include <iostream>
#include <vector>
#include "func.h"

using namespace std;

int main(int argc, char* argv[]) {
	cout << "Hello World!!!" << endl;

	cout << "compare('aaa','bbb'): " << compare("aaa", "bbb") << endl; // 普通调用

	int (*fp)(const string&, const string&);
	fp = compare;
	cout << "function pointer: " << fp("aaa", "bbb") << endl;  // 通过函数指针调用
	fp = &compare; // 和上面等价
	cout << "function pointer: " << fp("aaa", "bbb") << endl;

	string s1("aaa");
	string s2("bbb");
	myfun(&s1, &s2, fp);  // 把函数指针作为参数传到一个函数中去

	return 0;
}

运行结果:

Hello World!!!
compare('aaa','bbb'): -1
function pointer: -1
function pointer: -1
myfun:comp('aaa','bbb'): -1


二、static关键字

  1. 面向过程
      * static全局变量:只能在本文件中访问。和普通全局变量的区别就是作用域被限制在一个文件中
      * static局部变量:函数退出时仍保持其值不释放。普通的局部变量在函数退出时会被释放
      * static函数:只能在本文件中访问。普通函数通过extern的方式(一般定义在头文件中)可被用于其它文件中。
   2. 面向过程
      * static属性或方法:属于类而非某个对象。不能调用非static成员,当非static成员可以调用它。这个和JAVA没有区别

三、namespace

  作用就是在全局命名空间(::)中继续划分子空间。子空间的定义会覆盖父空间的定义。和JS中的域差不多。

1.定义
namespace MySpace {
   // 各种定义
   namespace InnerSpace1{ // 可以嵌套
      // 各种定义,会覆盖外层同名的定义
  }
}
2. 使用
  * MySpace::xxx // 直接使用域前缀的方式去访问该命名空间下的成员
  * using MS=MySpace; // 别名
     MS::xxx  // 使用域前缀的方式访问。类似于JAVA的全类名java.util.List
  * using MySpace::xxx; // 使xxx可见。类似于JAVA的import java.util.List;
    xxx.fun(); // 类似于JAVA的ist.add();
  * using MySpace; // 使该空间下的所有成员可见。类似于JAVA的import java.util.*;
    xxx.fun();


四、函数重载

 

  * 函数名相同,参数的个数、类型、顺序不同
  * 不考虑返回类型,不考虑参数名称
  * 不考虑形参的const,volatile修饰符 (指针和引用类型的除外)
  * 只考虑typedef所代表的底层类型
  * 不考虑形参是否缺省


五、函数的几种返回类型

class Test {
public :
	Test(){val=0;}
	Test(int v) {
		val = v;
	}
	~Test(){val=-1;}
	inline int get(){return val;}
    inline void set(int v){val = v;}
private :
	int val;
};

Test getTest1() {
//	Test t(100);
//	return t;  // 会调用拷贝构造,然后析构t

//	Test t(100);
//	Test &rt = t;
//	return rt;  // 同上

	Test *t = new Test(100);
	return *t; // 会照成内存泄露。函数结束后,t变量消失,但其所指向的对象没有释放(delete t)
}

Test& getTest2() {
//	Test t(100);
//	return t; // 函数结束后t被析构,返回值指向一个无效的内存区域

//	Test t(100);
//	Test& rt = t;
//	return rt;  // 同上

	Test *t = new Test(100);
	return *t; // 函数结束后t消失,而返回的引用指向了被new出来的内存。但是因为返回的不是一个指针,所以无法通过delete去释放这块内存,造成内存泄露
}

Test* getTest3() {
//	Test t(100);
//	return &t;  // 函数结束后t被析构,返回的指针变成野指针

//	Test t(100);
//	Test &rt = t;
//	return &rt;  // 同上

	Test *t = new Test(100);
	return t;  // 较好
}

void f () {
	Test t = getTest1();
	cout << t.get() << endl;

//	Test t = getTest2();
//	cout << t.get() << endl;

//	Test *pt = getTest3();
//	cout << pt->get() << endl;
}


int main(int argc, char* argv[]) {
	f();
	return 0;
}

六、引用基本知识

  引用的主要作用是: 1.函数形参   2. 函数返回值   3. const引用

int i = 100;
	int &ri = i;  // 引用的声明
	cout << "ri=" << ri << endl;
	int &rri = ri; // 这里的ri就是i,实际上相当于: int &rri = i;为i分配了第二个别名rri
	cout << "rri=" << rri << endl;
	int j = ri;  // 相当于i=j
	cout << "j=" << j << endl;

	int k = 200;
	const int &rk = k;  // 常引用
	//rk = 300; // 不能通过常引用去修改k
	k = 300; // 但是我们可以直接修改k
	cout << "rk=" << rk << endl; // 300
	int &nrk = k;  // k的第二个别名(注意是非const引用)
	nrk = 400; // 通过nrk可以修改k,此时的rk跟着一起变
	cout << "rk=" << rk << endl;




  




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值