C++學習筆記 —— 命名空間、內聯函數、按值/引用/指針傳遞

命名空間

問題出現

比如兩個頭文件中PeopleA.h和PeopleB.h 我們定義類兩個相同的Student類和普通函數func().
而我們在main文件中同時引入了這兩個頭文件,而如果我們想使用Student類或者普通函數func()時,編譯器就不知道我們要使用哪個了。
爲了解決命名衝突的問題。

//PeopleA.h
namespace PeopleA
{
class Student
{
private:
	/* data */
public:
	Student(/* args */);
	~Student();
};

int func()
{
}
} // namespace PeopleA

//PeopleB.h
namespace PeopleB
{
class Student
{
private:
	/* data */
public:
	Student(/* args */);
	~Student();
};

int func()
{
}
} // namespace PeopleB

#include "PeopleA.h"
#include "PeopleB.h"
int main()
{
	//顯示指明名字空間
	PeopleA::Student std1;
	PeopleA::func();
	PeopleB::Student std1;
	PeopleB::func();
}

使用命名空間的三種方式

  1. 直接使用
int main(){
	PeopleA::Student std1;
	PeopleA::func();
	PeopleB::Student std1;
	PeopleB::func();
	std::cout<<2;
}
  1. 使用using關鍵字
using std::cout;
using PeopleA::Student;
int main(){
	Student std1; //這時使用的是PeopleA
	cout<<2;
}
  1. 使用using namespace +名字空間 使用該名字空間下的所有成員
using namespace std;
using PeopleA::Student;
int main(){
	cout<<2;
}

內聯函數

什麼是內聯函數

內聯函數-C中關鍵字inline用法解析

​ 如果一些函數被頻繁調用,不斷地有函數入棧,即函數棧,會造成棧空間或棧內存的大量消耗。


inline char* dbtest(int a) 
{  
    return (i % 2 > 0) ? "奇" : "偶";  
}   
int main()  
{  
    int i = 0;  
    for (i=1; i < 100; i++) 
    {  
        printf("i:%d    奇偶性:%s /n", i, dbtest(i));      
    }  
}

慎用內聯

​ 內聯能提高函數的執行效率,爲什麼不把所有的函數都定義成內聯函數?
​ 內聯是以代碼膨脹(複製)爲代價,每一處內聯函數的調用都要複製代碼,將使程序的總代碼量增大,消耗更多的內存空間。

內聯函數使用

  1. 內聯函數不能包括複雜的控制語句,如循環語句和switch語句;
  2. 只將規模很小(一般5個語句一下)而使用頻繁的函數聲明爲內聯函數。在函數規模很小的情況下,函數調用的時間開銷可能相當於甚至超過執行函數本身的時間,把它定義爲內聯函數,可大大減少程序運行時間。

引用

引用的實質,就是起別名。
引用必須初始化,不能只聲明。

#include <iostream>
#include <cstring>

using namespace std;


int main()
{
   int a = 10;
   int &b = a;//放在等號左邊是起別名,放在等號右邊是取地址。
   b = 20;
   cout<< a; // 20  修改的就是原a的值
}

按值傳遞,引用傳遞,指針傳遞區別

值傳遞,引用傳遞,指針地址傳遞

#include <iostream>

using namespace std;

class Person
{
public:
	Person(int a) : num(a)
	{
	}
	~Person()
	{
	}
	void setNum(int a)
	{
		num = a;
	}
	void printNum()
	{
		cout << num << endl;
	}

private:
	int num;
};

//按值傳遞
void passByValue(Person p)
{
	//值傳遞,相當於創建一個新對象的副本
	p.setNum(100);
	p.printNum();
}
//按引用傳遞
void passByRef(Person &p)
{
	p.setNum(200);
	p.printNum();
}
//按指針傳遞
void passByPointer(Person *p)
{
	p->setNum(300);
	p->printNum();
}
int main()
{
	Person p1(0);	//初始化值0
	passByValue(p1); // 100
	p1.printNum();

	Person p2(0);
	passByRef(p2); //200 原對象中值被更改
	p2.printNum(); //200
	//所以一般使用該種方式來進行函數傳入對象,因爲可以修改傳入對象的值,這也是java使用中默認方式傳引用。因爲java沒有&取地址符號。

	Person p3(0);
	passByPointer(&p3); // 300
	p3.printNum();		// 300 傳遞的是對象的地址,函數對對象的改變直接操作原對象,直接改變
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章