2019年10月30日 星期三

make file

基本結構如下:

#--------------------------------------------------------------
target(要生成的文件): dependencies(被依賴的文件, Prerequisites)
#命令前面用的是「tab」而非空格。誤用空格是初學者容易犯的錯誤。
        command1
        command2
        command3
          .
          .
          .
        commandn
#可用「\」表示換行繼續,「\」後不能有空格
#--------------------------------------------------------------

說明:
1. target與dependencies中間用冒號(:)分隔開來
2. command前面是tab,不能是空白符號( ),會有錯誤,指令最後面也不能有空白符號( )
3. 註解(comment):符號為#
4. dependencies: 要完成target或產生target檔案,所需要的檔案
5. target: 透過dependencies與下面的command來完成


特殊target:

#--------------------------------------------------------------
clean:
        command1
        command2
        command3
#--------------------------------------------------------------
說明:
1. 這種沒目標文件或間接關聯,不會自動執行,不過我們執行: make clean

偽目標 .PHONY

#--------------------------------------------------------------
.PHONY: clean
clean:
        rm *.o
        rm *.exe
 #--------------------------------------------------------------
說明:
.PHONY 會將目標設成假target,使 make目錄下沒有目標檔案或目標檔案為最新時,仍可執行 make <target>
make預設的假target有 all, install, clean, distclean, TAGS, info 和 check

變數

#--------------------------------------------------------------
cc = gcc
src = a.cpp b.cpp c.cpp
program : $(src)
        $(cc) -c $(src)
#--------------------------------------------------------------
說明:
1. 變數宣告時,使用 = 或 := 給予初始值
2. 取用時,加入$(),如上面的$(src)
3. 特殊變數
3-1. $@ : target檔名
3-2. $< : 第一個dependencies檔名
3-3. $^ : 所有個dependencies的檔名, 並以空格隔開這些檔名(已經拿掉重複的檔名)
3-4. $* : target主檔名,但不含副檔名
4. 特殊等號
4-1. ?= : 若變數未定義,則替它指定新的值。否則,採用原有的值。
4-2. := : 變數的值決定於它在 Makefile 中的位置,而不是整個 Makefile 展開後最終的值
4-3. = : 變數的值為整個 Makefile 展開後最終的值
4-4. += : 把+=後面的內容,放入+=前面

萬用字元

#--------------------------------------------------------------
CC = gcc

%.o: %.c
  $(CC) -c -o $@ $<
#--------------------------------------------------------------
說明:
makefile中所用的萬用字元是 %,代表所有可能的字串。
target、個dependencies檔名可以接指定的字串來表示某些固定樣式的字串。
例:%.c 表示結尾是.c 的所有字串。

特別字元

#--------------------------------------------------------------
.PHONY: clean
clean:
    @echo "Clean..."
    -rm *.o
#--------------------------------------------------------------
說明:
1. @ : 不要顯示執行的command,因執行make後,會在終端機印出正在執行的指令
2. - : 即使執行出錯,也不會中斷執行,因make只要遇到錯誤,就會中斷執行。
故像上面沒有任何檔案可以rm時,rm傳回錯誤值,會導致 make 中斷執行。
利用 - 來關閉錯誤中斷功能,讓make不會因而中斷。

範例:

用makefile 建立資料夾
#--------------------------------------------------------------
OBJDIR = ./obj
$(OBJDIR):
    mkdir -p $@

makeDir: ${OBJDIR}
#--------------------------------------------------------------

2019年10月18日 星期五

const

A. 變數宣告

1. const char *tVar;
2. char const *tVar;
3. char * const tVar;
4. const char * const tVar;

加上括號方便了解

1. const (char) *tVar;-->把*tVar當作一個變數,所以*tVar的值,不可變
2. (char) const *tVar;-->同上
3. (char *) const tVar;-->tVar型別為(char *),tVar指標不可變, 右邊語法為一樣意思:const (char *) tVar;
4. const (char *) const tVar;-->指標與和指標所指到值,都不可變


B. Function內有const變數

1. void function(const int Var);
2. void function(const char *Var);
3. void function(char * const Var);

加上括號方便了解,其實就與需告變數同

1. void function(const (char) tVar);-->tVar傳function內,變數值不可變(無意義,tVar本身就傳進去參數)
2. void function(const (char) *tVar);-->*tVar型別為(char),*tVar的值不可變
3. void function((char *) const tVar);-->tVar型別為(char *),tVar指標不可變(無意義, tVar也是傳進去參數)


C. const 放在Function的回傳值

1. const int function()
2. const int *function()
3. int * const function()

加上括號方便了解,其實就與需告變數同

1. const (int) function()-->因回傳值是被assign的,所以沒意義
2. const (int) *function()-->把function()當成變數,應該較很清楚,*function()的值不可變。使用方式:const int *tValue = function();
3. (int *) const function()-->function()型別為(int *),回傳指標不可變。使用方式:int * const tValue = function();


D. const 拿來形容 object / object pointer / object reference

const 形容的物件,表示該物件為const物件,所以物件的任何member都不能改。object pointer / object reference 指到的物件也是一樣。
const 形容的物件,該物件的任何非const成員函數都不能被呼叫用,因為任何非const成員函數都可能有修改成員變數的企圖。

例:
class A
{
    void func1();
    void func2() const;
}

const AAA aObj;

aObj.func1();-->錯誤
aObj.func2();-->正確


const AAA* aObj = new AAA();

aObj->func1();-->錯誤
aObj->func2();-->正確


E. const 形容 class內的變數

class中有const的成員的值固定,不能被修改,且只能在初始化時,給值。
class A
{
    const int mVal;

    A(int mVal): nValue(mVal) {}; //初始化,給值
}


F. const 形容 class內的Function

class中有const的函數,不能修改class中任何非const成員函數。一般把const寫在函數最後。

class A
{
    void function() const; //const函式, 不改變物件的成員變數. 也不能呼叫任何非const成員函數。
}


G. const與define區別

1. compiler行為不同
define-->在compile前,即作取代動作
const-->compile時,處理

2. 類別和檢查行為不同
define-->沒有型別,不做型別檢查,只是展開。
const-->型別型別資訊,在compile時,會檢查。

3. 存儲方式不同
define-->僅展開,不會分配記憶體。
const-->會在記憶體中分配

參考網址:
const 放置位置的意義

2019年10月17日 星期四

Class Inheritance - Constructor, Destructor

#include <iostream>
using namespace std;

class A {
public:
    A() {
        cout << "A Constructor" << endl;
    }

    ~A() {
        cout << "A Cestructor" << endl;
    }
};

class B : public A {
public:
    B() {
        cout << "B Constructor" << endl;
    }

    ~B() {
        cout << "B Cestructor" << endl;
    }
};

int main() {
    B f;

    cout << endl;

    return 0;
}

執行結果:
A Constructor
B Constructor

B Cestructor
A Cestructor

static, extern in C, C++

extern

例:
xx.h
extern int a;

xx.cpp
int a = 100;

即:
    當別的cpp檔,include xx.h時,即告知linker a不在此.h與.cpp內,要去其他.o檔找。而build xx.h與xx.cpp時,會告知此a變數,可以給其他.o找到



Function或variable非class member


static function();(此變數宣告不在function裡)
static variable;(此變數宣告不在function裡)


A static function is a function whose scope is limited to the current source file.

即:
    此function只會在自己對應的.h與.cpp內被看到,當.h與.cpp被build成.o檔時,其他程式如果
需要link此function會看不到。同理,此變數只在此.h與.cpp內看的到。

static variable;(此變數宣告在function裡)

即:
    call完此function後,此variable依然存在,不會消失。



Function或variable是class member

class xxx{
  static int a;
  static void function();
}

即:
    此variable不屬於任何instance,而是屬於此class的,所有instance共用此變數,可用此變數來計算instance個數。
    此function不屬於任何instance,而是屬於此class的,未有instance即可呼叫此function。



參考:
[C/C++] 靜態函式 (static function) 2011
C/C++ 中的 static, extern 的變數