Define,const,static用法總結。本站提示廣大學習愛好者:(Define,const,static用法總結)文章只能為提供參考,不一定能成為您想要的結果。以下是Define,const,static用法總結正文
1、Define用法:
define重要是用於宏常量界說的,使法式看起來更簡練清楚明了,便利代碼保護,#define界說的本質只是一個常數的名字,沒有詳細數據類型的,沒有分派內存空間。在編譯是會被編譯器調換為該常數。每次應用該宏界說,就要停止編譯並分派空間,若一個法式中屢次應用define界說的數據,則就會有多份拷貝。這麼做是為了進步法式的可讀性,但平安性絕對差點。
2、const用法:
const界說的全局數據變量,其根本感化和define雷同,但又在define的基本上增長了很多多少功效。const界說的數據在法式開端前就在全局變量辨別配了空間,在法式履行的進程中,若用到該數據,直接讀取便可以,沒需要每次停止編譯,全部法式進程中也只要一個拷貝。關於const用法很多多少,如:
(1)界說常量
const int a=100; //界說a為一個全局數據區常量
const int *a=&i; //界說一個指向常量i的指針,個中*a是不克不及修正的
int * const a=&i; //界說一個常量指針 ,個中a是不克不及修正的
const int * const a=&i; //界說一個指向常量i的常量型指針
(2)const潤飾函數參數(包含傳值、傳址、援用)
void fun(const int a); //潤飾傳值,但這個用法是沒有效的,由於a自己就是要傳入數據的一個拷貝,是另分派的內存,所以對a的轉變,對本來數據是沒有影響的
void fun(const int *a); //潤飾傳址,要傳入的數據是一個地址,此時若法式中對*a停止修正,則本來的數據也會隨著修正,所以若不想轉變本來數據的值,只是願望在函數中援用該數據,則須要加const
void fun(const int &a); //潤飾援用,其功效和傳址是一樣的,援用就是給要傳入的數據起了一個體名。
關於潤飾援用,上面重點說一下:
當輸出通俗數據類型時,不須要加const潤飾,由於參數自己就是暫時分派到棧空間的拷貝,但如果參數是用戶自界說類型或類時,須要援用傳遞,由於可以進步效力。
void fun(A a); //A為用戶本身界說的類型,這類用法效力低,函數體內發生A類型的暫時對象復制參數a時,該暫時對象的結構、復制、析構進程都將消費時光。
void fun(const A& a); //這用用法效力高,援用傳遞不須要發生暫時對象,省了暫時對象的結構、復制、析構進程消費的時光。但光用援用有能夠轉變a,所以 加const。
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
Person()
{
cout<<"creat person"<<endl;
}
~Person()
{
cout<<"destroy person"<<endl;
}
virtual void fun() const
{
cout<<"hello person"<<endl;
}
};
class Student: public Person {
public:
Student()
{
cout<<"create student"<<endl;
}
~Student()
{
cout<<"desotry student"<<endl;
}
virtual void fun() const
{
cout<<"hello sudent"<<endl;
}
};
bool studentval(Student p)
{
p.fun();
return true;
}
int main(int argc,char *argv[])
{
Student pa;
cout<<endl;
studentval(pa);
cout<<endl;
return 0;
}
剖析:起首聲明Student pa時停止了兩次結構函數(student和person),再挪用studentval(pa)函數時,須要創立pa的暫時變量,即挪用了兩次拷貝結構函數(student和person),但該函數停止後,創立的暫時變量燒毀,挪用了兩次析構函數,而當main函數停止後,pa燒毀又挪用了兩次結構函數。共挪用了8次函數。若改成援用傳遞,及函數改成:
bool studentval(const Student& p)
{
p.fun();
return true;
}
由於援用傳遞時沒有結構暫時變量,也就不須要別的停止結構和析構了,就全部函數進程只須要4次挪用。
別的const潤飾援用還可以處理多態中的"割斷"成績,以下面代碼中多態的完成:
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
Person()
{
cout<<"creat person"<<endl;
}
~Person()
{
cout<<"destroy person"<<endl;
}
virtual void fun() const
{
cout<<"hello person"<<endl;
}
};
class Student: public Person {
public:
Student()
{
cout<<"create student"<<endl;
}
~Student()
{
cout<<"desotry student"<<endl;
}
virtual void fun() const //勿丟const
{
cout<<"hello sudent"<<endl;
}
};
bool studentval(Person p)
{
p.fun();
return true;
}
int main(int argc,char *argv[])
{
Student pa;
cout<<endl;
studentval(pa);
cout<<endl;
return 0;
}
按理說挪用studentval(Person p),當傳入Student類型的時刻,依照多態應當顯示的student的內容,即顯示"hello stuent",但成果顯示的倒是"hello person",解釋被割斷了,若改成bool studentval(const Person &p)時,便處理了該成績。
(3)const潤飾成員函數
void fun(int a) const
(4)const潤飾函數前往值
const int *fun(int a)
3、static用法:
函數外部界說的變量,在法式履行到它的界說處時,編譯器為它在棧上分派空間,年夜家曉得,函數在棧上分派的空間在此函數履行停止時會釋放失落,如許就發生了一個成績: 假如想將函數中此變量的值保留至下一次挪用時,若何完成?最輕易想到的辦法是界說一個全局的變量,但界說為一個全局變量有很多缺陷,最顯著的缺陷是損壞了此變量的拜訪規模(使得在此函數中界說的變量,不只僅受此函數掌握)。是以C++ 中引入了靜態變量static,用它來潤飾變量,它可以或許指導編譯器將此變量在法式的靜態存儲辨別配空間保留,如許即完成了目標,又使得此變量的存取規模不變。
關於部分變量而言,static轉變了變量的存儲方法,使其變成靜態存儲,銜接方法是外部銜接(只能在該文件中應用,部分變量原來就是外部銜接了),即部分變量只轉變存儲方法,不轉變銜接方法。關於全局變量而言,則不轉變存儲方法(全局變量曾經是靜態存儲了),它僅轉變其銜接類型,全局變量默許是外聯的,即能被其他內部文件直接應用,只需提早聲明extern,若加上static,則只能在本文件應用,即全局變量只轉變銜接方法,不轉變存儲方法。