国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) 後端開發(fā) C++ 用 C 建立健壯的日誌系統(tǒng)

用 C 建立健壯的日誌系統(tǒng)

Nov 29, 2024 am 01:00 AM

Creating a Robust Logging System in C

創(chuàng)建強(qiáng)大的軟體需要做出深思熟慮的設(shè)計(jì)選擇,以簡(jiǎn)化程式碼維護(hù)和擴(kuò)充功能。其中一個(gè)範(fàn)例是在 C 應(yīng)用程式中實(shí)作日誌記錄功能。日誌記錄不僅僅是列印錯(cuò)誤訊息;它是關(guān)於建立一個(gè)支援調(diào)試、分析甚至跨平臺(tái)相容性的結(jié)構(gòu)化系統(tǒng)。

在本文中,我們將受現(xiàn)實(shí)場(chǎng)景的啟發(fā),探索如何使用設(shè)計(jì)模式和最佳實(shí)踐逐步建立日誌系統(tǒng)。最後,您將對(duì)用 C 語(yǔ)言建立靈活且可擴(kuò)展的日誌系統(tǒng)有深入的了解。

目錄

  1. 日誌記錄的需要
  2. 組織日誌檔案
  3. 建立中央日誌功能
  4. 實(shí)作軟體模組過(guò)濾器
  5. 新增條件日誌記錄
  6. 正確管理資源
  7. 確保線程安全
  8. 外部與動(dòng)態(tài)配置
  9. 自訂日誌格式
  10. 內(nèi)部錯(cuò)誤處理
  11. 性能與效率
  12. 安全最佳實(shí)務(wù)
  13. 與日誌記錄工具整合
  14. 測(cè)試與驗(yàn)證
  15. 跨平臺(tái)文件記錄
  16. 把一切都包起來(lái)
  17. 額外

日誌記錄的需要

想像一下維護(hù)部署在遠(yuǎn)端站點(diǎn)的軟體系統(tǒng)。每當(dāng)出現(xiàn)問(wèn)題時(shí),您必須親自出差來(lái)調(diào)試問(wèn)題。隨著部署在地理上的擴(kuò)展,這種設(shè)定很快就會(huì)變得不切實(shí)際。記錄可以挽救局面。

日誌記錄提供了執(zhí)行過(guò)程中關(guān)鍵點(diǎn)的系統(tǒng)內(nèi)部狀態(tài)的詳細(xì)記錄。透過(guò)檢查日誌文件,開發(fā)人員可以診斷和解決問(wèn)題,而無(wú)需直接重現(xiàn)問(wèn)題。這對(duì)於難以在受控環(huán)境中重新建立的偶發(fā)錯(cuò)誤特別有用。

日誌記錄的價(jià)值在多執(zhí)行緒應(yīng)用程式中變得更加明顯,其中錯(cuò)誤可能取決於時(shí)間和競(jìng)爭(zhēng)條件。在沒(méi)有日誌的情況下調(diào)試這些問(wèn)題需要大量的努力和專門的工具,而這些工具可能並不總是可用。日誌提供了所發(fā)生事件的快照,有助於找出根本原因。

然而,日誌記錄不僅僅是一個(gè)簡(jiǎn)單的功能——它是一個(gè)系統(tǒng)。實(shí)施不當(dāng)?shù)娜照I記錄機(jī)制可能會(huì)導(dǎo)致效能問(wèn)題、安全漏洞和不可維護(hù)的程式碼。因此,在設(shè)計(jì)日誌系統(tǒng)時(shí),遵循結(jié)構(gòu)化方法和模式至關(guān)重要。

組織記錄文件

正確的文件組織對(duì)於保持程式碼庫(kù)在成長(zhǎng)時(shí)的可維護(hù)性至關(guān)重要。日誌記錄作為一項(xiàng)獨(dú)特的功能,應(yīng)該隔離到自己的模組中,以便輕鬆定位和修改,而不影響程式碼的不相關(guān)部分。

頭檔(logger.h):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

實(shí)作檔案(logger.c):

#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}

用法(main.c):

#include "logger.h"

int main() {
    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");
    return 0;
}

編譯並執(zhí)行:

要編譯並執(zhí)行此範(fàn)例,請(qǐng)?jiān)诮K端機(jī)中使用以下命令:

gcc -o app main.c logger.c
./app

預(yù)期輸出:

[Mon Sep 27 14:00:00 2021
] Application started
[Mon Sep 27 14:00:00 2021
] Performing operation...
[Mon Sep 27 14:00:00 2021
] Operation completed.

第一步是建立一個(gè)用於日誌記錄的專用目錄。該目錄應(yīng)包含所有相關(guān)的實(shí)作檔案。例如,logger.c 可以包含日誌系統(tǒng)的核心邏輯,而 logger_test.c 可以保存單元測(cè)試。將相關(guān)文件放在一起可以提高開發(fā)團(tuán)隊(duì)內(nèi)的清晰度和協(xié)作性。

此外,日誌記錄介面應(yīng)透過(guò)頭檔(例如 logger.h)公開,並放置在適當(dāng)?shù)哪夸浿?,例?include/ 或與原始檔案相同的目錄。這確保了需要日誌記錄功能的其他模組可以輕鬆存取它。將頭檔與實(shí)作檔分開也支援封裝,向日誌記錄 API 的使用者隱藏實(shí)作細(xì)節(jié)。

最後,對(duì)目錄和檔案採(cǎi)用一致的命名約定可以進(jìn)一步增強(qiáng)可維護(hù)性。例如,使用 logger.h 和 logger.c 可以清楚地表明這些檔案屬於日誌記錄模組。避免將不相關(guān)的程式碼混合到日誌記錄模組中,因?yàn)檫@違背了模組化的目的。

建立中央日誌記錄功能

任何日誌系統(tǒng)的核心都有一個(gè)處理核心操作的核心功能:記錄日誌訊息。此功能的設(shè)計(jì)應(yīng)考慮簡(jiǎn)單性和可擴(kuò)展性,以支援未來(lái)的增強(qiáng)功能,而無(wú)需進(jìn)行重大更改。

實(shí)作(logger.c):

#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>

#define BUFFER_SIZE 256
static_assert(BUFFER_SIZE >= 64, "Buffer size is too small");

void log_message(const char* text) {
    char buffer[BUFFER_SIZE];
    time_t now = time(NULL);

    if (!text) {
        fprintf(stderr, "Error: Null message passed to log_message\n");
        return;
    }

    snprintf(buffer, BUFFER_SIZE, "[%s] %s", ctime(&now), text);
    printf("%s", buffer);
}

注意:使用 static_assert 需要 C11 或更高版本。確保您的編譯器支援此標(biāo)準(zhǔn)。

基本的日誌記錄功能可以透過(guò)將訊息列印到標(biāo)準(zhǔn)輸出來(lái)啟動(dòng)。在每個(gè)日誌條目中新增時(shí)間戳記可以透過(guò)提供時(shí)間上下文來(lái)提高其實(shí)用性。例如,日誌可以幫助識(shí)別特定錯(cuò)誤何時(shí)發(fā)生或事件如何隨著時(shí)間的推移而展開。

為了保持日誌記錄模組無(wú)狀態(tài),請(qǐng)避免在函數(shù)呼叫之間保留任何內(nèi)部狀態(tài)。這種設(shè)計(jì)選擇簡(jiǎn)化了實(shí)現(xiàn),並確保模組在多線程環(huán)境中無(wú)縫工作。無(wú)狀態(tài)模組也更容易測(cè)試和調(diào)試,因?yàn)樗鼈兊男袨椴灰蕾囅惹暗幕?dòng)。

設(shè)計(jì)日誌記錄功能時(shí)考慮錯(cuò)誤處理。例如,如果將 NULL 指標(biāo)作為日誌訊息傳遞,會(huì)發(fā)生什麼情況?遵循“武士原則”,該函數(shù)應(yīng)該要么優(yōu)雅地處理這個(gè)問(wèn)題,要么立即失敗,從而使調(diào)試更容易。

實(shí)作軟體模組過(guò)濾器

隨著應(yīng)用程式變得越來(lái)越複雜,它們的日誌輸出可能會(huì)變得難以承受。如果沒(méi)有過(guò)濾器,來(lái)自不相關(guān)模組的日誌可能會(huì)淹沒(méi)控制臺(tái),從而難以關(guān)注相關(guān)資訊。實(shí)施過(guò)濾器可確保僅記錄所需的日誌。

為了實(shí)現(xiàn)這一點(diǎn),引入一種機(jī)制來(lái)追蹤啟用的模組。這可以像全域列表一樣簡(jiǎn)單,也可以像動(dòng)態(tài)分配的雜湊表一樣複雜。此清單儲(chǔ)存模組名稱,並且僅處理來(lái)自這些模組的日誌。

過(guò)濾是透過(guò)在日誌記錄函數(shù)中新增模組參數(shù)來(lái)實(shí)現(xiàn)的。在寫入日誌之前,函數(shù)會(huì)檢查模組是否已啟用。如果不是,它會(huì)跳過(guò)日誌條目。這種方法使日誌記錄輸出簡(jiǎn)潔並集中在感興趣的領(lǐng)域。這是過(guò)濾的範(fàn)例實(shí)作:

頭檔(logger.h):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

實(shí)作檔案(logger.c):

#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}

此實(shí)作在簡(jiǎn)單性和功能性之間取得了平衡,為特定於模組的日誌記錄提供了堅(jiān)實(shí)的起點(diǎn)。

新增條件日誌記錄

條件日誌記錄對(duì)於建立適應(yīng)不同環(huán)境或運(yùn)行時(shí)條件的靈活系統(tǒng)至關(guān)重要。例如,在開發(fā)過(guò)程中,您可能需要詳細(xì)的偵錯(cuò)日誌來(lái)追蹤應(yīng)用程式行為。在生產(chǎn)中,您可能更願(yuàn)意僅記錄警告和錯(cuò)誤,以最大限度地減少效能開銷。

實(shí)現(xiàn)此目的的一種方法是引入日誌等級(jí)。常見等級(jí)包括偵錯(cuò)、資訊、警告和錯(cuò)誤。日誌記錄功能可以為日誌等級(jí)新增一個(gè)附加參數(shù),只有當(dāng)日誌等級(jí)達(dá)到或超過(guò)目前閾值時(shí)才會(huì)記錄日誌。這種方法可確保過(guò)濾掉不相關(guān)的訊息,從而保持日誌簡(jiǎn)潔且有用。

為了使其可配置,您可以使用全域變數(shù)來(lái)儲(chǔ)存日誌等級(jí)閾值。然後,應(yīng)用程式可以動(dòng)態(tài)調(diào)整此閾值,例如透過(guò)設(shè)定檔或運(yùn)行時(shí)命令。

頭檔(logger.h):

#include "logger.h"

int main() {
    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");
    return 0;
}

實(shí)作檔案(logger.c):

gcc -o app main.c logger.c
./app

此實(shí)作可以輕鬆控制日誌記錄的詳細(xì)程度。例如,您可以在故障排除工作階段期間將日誌等級(jí)設(shè)定為 DEBUG,並在生產(chǎn)中將其還原為 WARNING。

正確管理資源

適當(dāng)?shù)馁Y源管理至關(guān)重要,尤其是在處理文件操作或多個(gè)日誌記錄目的地時(shí)。未能關(guān)閉檔案或釋放分配的記憶體可能會(huì)導(dǎo)致資源洩漏,隨著時(shí)間的推移會(huì)降低系統(tǒng)效能。

確保為記錄而開啟的任何檔案在不再需要時(shí)正確關(guān)閉。這可以透過(guò)實(shí)作初始化和關(guān)閉日誌系統(tǒng)的函數(shù)來(lái)實(shí)現(xiàn)。

實(shí)作(logger.c):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

用法(main.c):

#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}

編譯並執(zhí)行:

#include "logger.h"

int main() {
    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");
    return 0;
}

這會(huì)將日誌訊息寫入 application.log。透過(guò)提供 init_logging 和 close_logging 函數(shù),您可以讓應(yīng)用程式控制日誌記錄資源的生命週期,防止洩漏和存取問(wèn)題。

確保線程安全

在多執(zhí)行緒應(yīng)用程式中,日誌記錄函數(shù)必須是執(zhí)行緒安全的,以防止競(jìng)爭(zhēng)條件並確保日誌訊息不會(huì)交錯(cuò)或損壞。

實(shí)作執(zhí)行緒安全的一種方法是使用互斥體或其他同步機(jī)制。

實(shí)作(logger.c):

gcc -o app main.c logger.c
./app

多執(zhí)行緒環(huán)境中的使用(main.c):

[Mon Sep 27 14:00:00 2021
] Application started
[Mon Sep 27 14:00:00 2021
] Performing operation...
[Mon Sep 27 14:00:00 2021
] Operation completed.

編譯並執(zhí)行:

#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>

#define BUFFER_SIZE 256
static_assert(BUFFER_SIZE >= 64, "Buffer size is too small");

void log_message(const char* text) {
    char buffer[BUFFER_SIZE];
    time_t now = time(NULL);

    if (!text) {
        fprintf(stderr, "Error: Null message passed to log_message\n");
        return;
    }

    snprintf(buffer, BUFFER_SIZE, "[%s] %s", ctime(&now), text);
    printf("%s", buffer);
}

這可以確保來(lái)自不同執(zhí)行緒的日誌不會(huì)相互幹?jǐn)_,從而保持日誌訊息的完整性。

外部和動(dòng)態(tài)配置

允許在外部設(shè)定日誌配置增強(qiáng)了靈活性。日誌等級(jí)、啟用的模組和目標(biāo)等配置可以從設(shè)定檔載入或透過(guò)命令列參數(shù)設(shè)定。

設(shè)定檔(config.cfg):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdbool.h>

void enable_module(const char* module);
void disable_module(const char* module);
void log_message(const char* module, const char* text);

#endif // LOGGER_H

實(shí)作(logger.c):

#include "logger.h"
#include <stdio.h>
#include <string.h>

#define MAX_MODULES 10
#define MODULE_NAME_LENGTH 20

static char enabled_modules[MAX_MODULES][MODULE_NAME_LENGTH];

void enable_module(const char* module) {
    for (int i = 0; i < MAX_MODULES; i++) {
        if (enabled_modules[i][0] == '<pre class="brush:php;toolbar:false">#ifndef LOGGER_H
#define LOGGER_H

typedef enum { DEBUG, INFO, WARNING, ERROR } LogLevel;

void set_log_level(LogLevel level);
void log_message(LogLevel level, const char* module, const char* text);

#endif // LOGGER_H
') { strncpy(enabled_modules[i], module, MODULE_NAME_LENGTH - 1); enabled_modules[i][MODULE_NAME_LENGTH - 1] = '
#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <string.h>

static LogLevel current_log_level = INFO;

void set_log_level(LogLevel level) {
    current_log_level = level;
}

void log_message(LogLevel level, const char* module, const char* text) {
    if (level < current_log_level) {
        return;
    }
    const char* level_strings[] = { "DEBUG", "INFO", "WARNING", "ERROR" };
    time_t now = time(NULL);
    printf("[%s][%s][%s] %s\n", ctime(&now), level_strings[level], module, text);
}
'; break; } } } void disable_module(const char* module) { for (int i = 0; i < MAX_MODULES; i++) { if (strcmp(enabled_modules[i], module) == 0) { enabled_modules[i][0] = '
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>

static FILE* log_file = NULL;

void init_logging(const char* filename) {
    if (filename) {
        log_file = fopen(filename, "a");
        if (!log_file) {
            fprintf(stderr, "Failed to open log file: %s\n", filename);
            exit(EXIT_FAILURE);
        }
    } else {
        log_file = stdout; // Default to standard output
    }
}

void close_logging() {
    if (log_file && log_file != stdout) {
        fclose(log_file);
        log_file = NULL;
    }
}

void log_message(const char* text) {
    if (!log_file) {
        fprintf(stderr, "Logging not initialized.\n");
        return;
    }
    time_t now = time(NULL);
    fprintf(log_file, "[%s] %s\n", ctime(&now), text);
    fflush(log_file); // Ensure the message is written immediately
}
'; break; } } } static int is_module_enabled(const char* module) { for (int i = 0; i < MAX_MODULES; i++) { if (strcmp(enabled_modules[i], module) == 0) { return 1; } } return 0; } void log_message(const char* module, const char* text) { if (!is_module_enabled(module)) { return; } time_t now = time(NULL); printf("[%s][%s] %s\n", ctime(&now), module, text); }

用法(main.c):

#include "logger.h"

int main() {
    init_logging("application.log");

    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");

    close_logging();
    return 0;
}

編譯並執(zhí)行:

gcc -o app main.c logger.c
./app

透過(guò)實(shí)現(xiàn)動(dòng)態(tài)配置,您可以調(diào)整日誌記錄行為而無(wú)需重新編譯應(yīng)用程序,這在生產(chǎn)環(huán)境中特別有用。

自訂日誌格式

自訂日誌訊息的格式可以使其資訊更豐富且更易於解析,尤其是在與日誌分析工具整合時(shí)。

實(shí)作(logger.c):

#include "logger.h"
#include <pthread.h>

static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;

void log_message(const char* text) {
    pthread_mutex_lock(&log_mutex);
    // Existing logging code
    if (!log_file) {
        fprintf(stderr, "Logging not initialized.\n");
        pthread_mutex_unlock(&log_mutex);
        return;
    }
    time_t now = time(NULL);
    fprintf(log_file, "[%s] %s\n", ctime(&now), text);
    fflush(log_file);
    pthread_mutex_unlock(&log_mutex);
}

範(fàn)例輸出:

#include "logger.h"
#include <pthread.h>

void* thread_function(void* arg) {
    char* thread_name = (char*)arg;
    for (int i = 0; i < 5; i++) {
        char message[50];
        sprintf(message, "%s: Operation %d", thread_name, i + 1);
        log_message(message);
    }
    return NULL;
}

int main() {
    init_logging("application.log");

    pthread_t thread1, thread2;

    pthread_create(&thread1, NULL, thread_function, "Thread1");
    pthread_create(&thread2, NULL, thread_function, "Thread2");

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    close_logging();
    return 0;
}

對(duì)於結(jié)構(gòu)化日誌記錄,請(qǐng)考慮以 JSON 格式輸出日誌:

gcc -pthread -o app main.c logger.c
./app

這種格式適合日誌管理工具解析。

內(nèi)部錯(cuò)誤處理

日誌系統(tǒng)本身可能會(huì)遇到錯(cuò)誤,例如無(wú)法開啟檔案或資源分配問(wèn)題。妥善處理這些錯(cuò)誤並向開發(fā)人員提供回饋非常重要。

實(shí)作(logger.c):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

透過(guò)在使用前檢查資源狀態(tài)並提供有意義的錯(cuò)誤訊息,您可以防止崩潰並幫助排除日誌系統(tǒng)本身的問(wèn)題。

性能和效率

日誌記錄會(huì)影響應(yīng)用程式效能,尤其是在日誌記錄範(fàn)圍廣泛或同步執(zhí)行的情況下。為了緩解這種情況,請(qǐng)考慮緩衝日誌或非同步執(zhí)行日誌記錄操作等技術(shù)。

非同步日誌實(shí)作(logger.c):

#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}

用法(main.c):

#include "logger.h"

int main() {
    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");
    return 0;
}

使用非同步日誌記錄可以減少主應(yīng)用程式執(zhí)行緒在日誌記錄上花費(fèi)的時(shí)間,從而提高整體效能。

安全最佳實(shí)踐

日誌可能會(huì)無(wú)意中暴露敏感訊息,例如密碼或個(gè)人資料。避免記錄此類資訊並保護(hù)日誌檔案免遭未經(jīng)授權(quán)的存取至關(guān)重要。

實(shí)作(logger.c):

gcc -o app main.c logger.c
./app

設(shè)定檔權(quán)限:

[Mon Sep 27 14:00:00 2021
] Application started
[Mon Sep 27 14:00:00 2021
] Performing operation...
[Mon Sep 27 14:00:00 2021
] Operation completed.

推薦:

  • 清理輸入:確保日誌訊息中不包含敏感資料。
  • 存取控制:對(duì)日誌檔案設(shè)定適當(dāng)?shù)臋?quán)限以限制存取。
  • 加密:如果日誌檔案包含敏感訊息,請(qǐng)考慮對(duì)其進(jìn)行加密。
  • 日誌輪替:實(shí)作日誌輪替以防止日誌無(wú)限增長(zhǎng)並管理暴露。

遵循這些做法,您可以增強(qiáng)應(yīng)用程式的安全性並遵守資料保護(hù)法規(guī)。

與日誌記錄工具集成

現(xiàn)代應(yīng)用程式通常與外部日誌記錄工具和服務(wù)集成,以實(shí)現(xiàn)更好的日誌管理和分析。

系統(tǒng)日誌整合(logger.c):

#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>

#define BUFFER_SIZE 256
static_assert(BUFFER_SIZE >= 64, "Buffer size is too small");

void log_message(const char* text) {
    char buffer[BUFFER_SIZE];
    time_t now = time(NULL);

    if (!text) {
        fprintf(stderr, "Error: Null message passed to log_message\n");
        return;
    }

    snprintf(buffer, BUFFER_SIZE, "[%s] %s", ctime(&now), text);
    printf("%s", buffer);
}

用法(main.c):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdbool.h>

void enable_module(const char* module);
void disable_module(const char* module);
void log_message(const char* module, const char* text);

#endif // LOGGER_H

遠(yuǎn)端記錄服務(wù):

要將日誌傳送到 Graylog 或 Elasticsearch 等遠(yuǎn)端服務(wù),您可以使用網(wǎng)路套接字或?qū)S煤綆?kù)。

使用套接字的範(fàn)例(logger.c):

#include "logger.h"
#include <stdio.h>
#include <string.h>

#define MAX_MODULES 10
#define MODULE_NAME_LENGTH 20

static char enabled_modules[MAX_MODULES][MODULE_NAME_LENGTH];

void enable_module(const char* module) {
    for (int i = 0; i < MAX_MODULES; i++) {
        if (enabled_modules[i][0] == '<pre class="brush:php;toolbar:false">#ifndef LOGGER_H
#define LOGGER_H

typedef enum { DEBUG, INFO, WARNING, ERROR } LogLevel;

void set_log_level(LogLevel level);
void log_message(LogLevel level, const char* module, const char* text);

#endif // LOGGER_H
') { strncpy(enabled_modules[i], module, MODULE_NAME_LENGTH - 1); enabled_modules[i][MODULE_NAME_LENGTH - 1] = '
#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <string.h>

static LogLevel current_log_level = INFO;

void set_log_level(LogLevel level) {
    current_log_level = level;
}

void log_message(LogLevel level, const char* module, const char* text) {
    if (level < current_log_level) {
        return;
    }
    const char* level_strings[] = { "DEBUG", "INFO", "WARNING", "ERROR" };
    time_t now = time(NULL);
    printf("[%s][%s][%s] %s\n", ctime(&now), level_strings[level], module, text);
}
'; break; } } } void disable_module(const char* module) { for (int i = 0; i < MAX_MODULES; i++) { if (strcmp(enabled_modules[i], module) == 0) { enabled_modules[i][0] = '
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>

static FILE* log_file = NULL;

void init_logging(const char* filename) {
    if (filename) {
        log_file = fopen(filename, "a");
        if (!log_file) {
            fprintf(stderr, "Failed to open log file: %s\n", filename);
            exit(EXIT_FAILURE);
        }
    } else {
        log_file = stdout; // Default to standard output
    }
}

void close_logging() {
    if (log_file && log_file != stdout) {
        fclose(log_file);
        log_file = NULL;
    }
}

void log_message(const char* text) {
    if (!log_file) {
        fprintf(stderr, "Logging not initialized.\n");
        return;
    }
    time_t now = time(NULL);
    fprintf(log_file, "[%s] %s\n", ctime(&now), text);
    fflush(log_file); // Ensure the message is written immediately
}
'; break; } } } static int is_module_enabled(const char* module) { for (int i = 0; i < MAX_MODULES; i++) { if (strcmp(enabled_modules[i], module) == 0) { return 1; } } return 0; } void log_message(const char* module, const char* text) { if (!is_module_enabled(module)) { return; } time_t now = time(NULL); printf("[%s][%s] %s\n", ctime(&now), module, text); }

用法(main.c):

#include "logger.h"

int main() {
    init_logging("application.log");

    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");

    close_logging();
    return 0;
}

與外部工具整合可以提供集中日誌管理、即時(shí)監(jiān)控和警報(bào)等進(jìn)階功能。

測(cè)試和驗(yàn)證

徹底的測(cè)試確保日誌系統(tǒng)在各種條件下都能正常運(yùn)作。

單元測(cè)試範(fàn)例(test_logger.c):

gcc -o app main.c logger.c
./app

編譯並執(zhí)行測(cè)試:

#include "logger.h"
#include <pthread.h>

static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;

void log_message(const char* text) {
    pthread_mutex_lock(&log_mutex);
    // Existing logging code
    if (!log_file) {
        fprintf(stderr, "Logging not initialized.\n");
        pthread_mutex_unlock(&log_mutex);
        return;
    }
    time_t now = time(NULL);
    fprintf(log_file, "[%s] %s\n", ctime(&now), text);
    fflush(log_file);
    pthread_mutex_unlock(&log_mutex);
}

檢定策略:

  • 單元檢定:驗(yàn)證各個(gè)函數(shù)。
  • 壓力測(cè)試:類比高頻日誌記錄。
  • 多執(zhí)行緒測(cè)試: 同時(shí)從多個(gè)執(zhí)行緒記錄。
  • 故障注入:模擬磁碟已滿或網(wǎng)路故障等錯(cuò)誤。

透過(guò)嚴(yán)格測(cè)試日誌系統(tǒng),您可以在問(wèn)題影響生產(chǎn)環(huán)境之前識(shí)別並修復(fù)問(wèn)題。

跨平臺(tái)文件記錄

跨平臺(tái)相容性是現(xiàn)代軟體的必要條件。雖然前面的範(fàn)例在基於 Unix 的系統(tǒng)上運(yùn)作良好,但由於檔案處理 API 的差異,它們可能無(wú)法在 Windows 上運(yùn)作。為了解決這個(gè)問(wèn)題,您需要一個(gè)跨平臺(tái)的日誌機(jī)制。

實(shí)作(logger.c):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

用法(logger.c):

#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}

透過(guò)隔離特定於平臺(tái)的詳細(xì)信息,您可以確保主要日誌記錄邏輯保持乾淨(jìng)且一致。

總結(jié)一切

設(shè)計(jì)日誌系統(tǒng)乍看之下似乎是一項(xiàng)簡(jiǎn)單的任務(wù),但正如我們所見,它涉及許多影響功能、效能和可維護(hù)性的決策。透過(guò)使用設(shè)計(jì)模式和結(jié)構(gòu)化方法,您可以建立一個(gè)健全、可擴(kuò)展且易於整合的日誌系統(tǒng)。

從組織文件到實(shí)現(xiàn)跨平臺(tái)相容性,每一步都建立在前一步的基礎(chǔ)上,形成一個(gè)有凝聚力的整體。系統(tǒng)可以按模組過(guò)濾日誌,透過(guò)日誌等級(jí)調(diào)整詳細(xì)程度,支援多個(gè)目的地,並正確處理資源。它確保線程安全,允許外部配置,支援自訂格式,並遵守安全最佳實(shí)踐。

透過(guò)採(cǎi)用無(wú)狀態(tài)設(shè)計(jì)動(dòng)態(tài)介面抽象層等模式,您可以避免常見的陷阱並使您的程式碼庫(kù)面向未來(lái)。無(wú)論您是在開發(fā)小型實(shí)用程式還是大型應(yīng)用程序,這些原則都是非常寶貴的。

您在建立精心設(shè)計(jì)的日誌系統(tǒng)方面投入的精力會(huì)得到回報(bào),減少調(diào)試時(shí)間,更好地洞察應(yīng)用程式行為,並提高利害關(guān)係人的滿意度。有了這個(gè)基礎(chǔ),您現(xiàn)在就可以處理最複雜專案的日誌記錄需求。

額外:增強(qiáng)日誌系統(tǒng)

在這個(gè)額外的部分中,我們將解決先前確定的一些需要改進(jìn)的領(lǐng)域,以增強(qiáng)我們建立的日誌系統(tǒng)。我們將專注於改進(jìn)程式碼一致性、改進(jìn)錯(cuò)誤處理、闡明複雜概念以及擴(kuò)展測(cè)試和驗(yàn)證。每個(gè)主題都包含介紹文字、可編譯的實(shí)際範(fàn)例以及供進(jìn)一步學(xué)習(xí)的外部參考資料。

1. 程式碼一致性和格式

一致的程式碼格式和命名約定提高了可讀性和可維護(hù)性。我們將使用 Snake_case 標(biāo)準(zhǔn)化變數(shù)和函數(shù)名稱,這在 C 程式設(shè)計(jì)中很常見。

更新的實(shí)作 (logger.h):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

更新的實(shí)作 (logger.c):

#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}

更新用法(main.c):

#include "logger.h"

int main() {
    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");
    return 0;
}

編譯並執(zhí)行:

gcc -o app main.c logger.c
./app

外部參考:

  • GNU 編碼標(biāo)準(zhǔn):命名約定
  • Linux 核心編碼風(fēng)格

2. 改進(jìn)的錯(cuò)誤處理

強(qiáng)大的錯(cuò)誤處理功能確保應(yīng)用程式能夠優(yōu)雅地處理意外情況。

增強(qiáng)的錯(cuò)誤檢查(logger.c):

[Mon Sep 27 14:00:00 2021
] Application started
[Mon Sep 27 14:00:00 2021
] Performing operation...
[Mon Sep 27 14:00:00 2021
] Operation completed.

外部參考:

  • C 中的錯(cuò)誤處理
  • C 語(yǔ)言的斷言

3. 澄清非同步日誌記錄

非同步日誌記錄透過(guò)將日誌記錄流程與主應(yīng)用程式流程分開來(lái)提高效能。這裡有一個(gè)實(shí)際例子的詳細(xì)解釋。

實(shí)作(logger.c):

#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <assert.h>

#define BUFFER_SIZE 256
static_assert(BUFFER_SIZE >= 64, "Buffer size is too small");

void log_message(const char* text) {
    char buffer[BUFFER_SIZE];
    time_t now = time(NULL);

    if (!text) {
        fprintf(stderr, "Error: Null message passed to log_message\n");
        return;
    }

    snprintf(buffer, BUFFER_SIZE, "[%s] %s", ctime(&now), text);
    printf("%s", buffer);
}

用法(main.c):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdbool.h>

void enable_module(const char* module);
void disable_module(const char* module);
void log_message(const char* module, const char* text);

#endif // LOGGER_H

編譯並執(zhí)行:

#include "logger.h"
#include <stdio.h>
#include <string.h>

#define MAX_MODULES 10
#define MODULE_NAME_LENGTH 20

static char enabled_modules[MAX_MODULES][MODULE_NAME_LENGTH];

void enable_module(const char* module) {
    for (int i = 0; i < MAX_MODULES; i++) {
        if (enabled_modules[i][0] == '<pre class="brush:php;toolbar:false">#ifndef LOGGER_H
#define LOGGER_H

typedef enum { DEBUG, INFO, WARNING, ERROR } LogLevel;

void set_log_level(LogLevel level);
void log_message(LogLevel level, const char* module, const char* text);

#endif // LOGGER_H
') { strncpy(enabled_modules[i], module, MODULE_NAME_LENGTH - 1); enabled_modules[i][MODULE_NAME_LENGTH - 1] = '
#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <string.h>

static LogLevel current_log_level = INFO;

void set_log_level(LogLevel level) {
    current_log_level = level;
}

void log_message(LogLevel level, const char* module, const char* text) {
    if (level < current_log_level) {
        return;
    }
    const char* level_strings[] = { "DEBUG", "INFO", "WARNING", "ERROR" };
    time_t now = time(NULL);
    printf("[%s][%s][%s] %s\n", ctime(&now), level_strings[level], module, text);
}
'; break; } } } void disable_module(const char* module) { for (int i = 0; i < MAX_MODULES; i++) { if (strcmp(enabled_modules[i], module) == 0) { enabled_modules[i][0] = '
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>

static FILE* log_file = NULL;

void init_logging(const char* filename) {
    if (filename) {
        log_file = fopen(filename, "a");
        if (!log_file) {
            fprintf(stderr, "Failed to open log file: %s\n", filename);
            exit(EXIT_FAILURE);
        }
    } else {
        log_file = stdout; // Default to standard output
    }
}

void close_logging() {
    if (log_file && log_file != stdout) {
        fclose(log_file);
        log_file = NULL;
    }
}

void log_message(const char* text) {
    if (!log_file) {
        fprintf(stderr, "Logging not initialized.\n");
        return;
    }
    time_t now = time(NULL);
    fprintf(log_file, "[%s] %s\n", ctime(&now), text);
    fflush(log_file); // Ensure the message is written immediately
}
'; break; } } } static int is_module_enabled(const char* module) { for (int i = 0; i < MAX_MODULES; i++) { if (strcmp(enabled_modules[i], module) == 0) { return 1; } } return 0; } void log_message(const char* module, const char* text) { if (!is_module_enabled(module)) { return; } time_t now = time(NULL); printf("[%s][%s] %s\n", ctime(&now), module, text); }

說(shuō)明:

  • 生產(chǎn)者-消費(fèi)者模型:主執(zhí)行緒產(chǎn)生日誌訊息並將它們加入佇列。日誌工作執(zhí)行緒消耗佇列中的消息並將其寫入日誌檔案。
  • 執(zhí)行緒同步:互斥體和條件變數(shù)確保對(duì)共享資源的執(zhí)行緒安全存取。
  • 正常關(guān)閉:logging_active 標(biāo)誌和條件變數(shù)會(huì)在日誌記錄關(guān)閉時(shí)通知工作執(zhí)行緒退出。

外部參考:

  • 生產(chǎn)者-消費(fèi)者問(wèn)題
  • POSIX 執(zhí)行緒程式設(shè)計(jì)

4. 擴(kuò)大測(cè)試和驗(yàn)證

測(cè)試對(duì)於確保日誌系統(tǒng)在各種條件下正常運(yùn)作至關(guān)重要。

使用 Unity 測(cè)試框架:

Unity 是一個(gè)輕量級(jí)的 C 測(cè)試框架。

設(shè)定:

  1. 從官方儲(chǔ)存庫(kù)下載Unity:GitHub 上的Unity
  2. 在您的測(cè)試文件中包含 unity.h。

測(cè)試檔(test_logger.c):

#include "logger.h"

int main() {
    init_logging("application.log");

    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");

    close_logging();
    return 0;
}

編譯並執(zhí)行測(cè)試:

gcc -o app main.c logger.c
./app

說(shuō)明:

  • setUp 和tearDown: 在每次設(shè)定和清理測(cè)試之前和之後運(yùn)行的函數(shù)。
  • 斷言: 使用 TEST_ASSERT_* 巨集來(lái)驗(yàn)證條件。
  • 測(cè)試案例:測(cè)試涵蓋記錄到標(biāo)準(zhǔn)輸出和檔案。

外部參考:

  • 統(tǒng)一測(cè)試框架
  • C 語(yǔ)言的單元測(cè)驗(yàn)

5. 安全增強(qiáng)

確保日誌系統(tǒng)的安全至關(guān)重要,尤其是在處理敏感資料時(shí)。

使用 TLS 安全傳輸:

要透過(guò)網(wǎng)路安全地傳送日誌,請(qǐng)使用 TLS 加密。

使用 OpenSSL 實(shí)作(logger.c):

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <time.h>

// Function prototypes
void log_message(const char* text);

#endif // LOGGER_H

外部參考:

  • OpenSSL 文件
  • 使用 OpenSSL 進(jìn)行安全程式設(shè)計(jì)

遵守資料保護(hù)法規(guī):

記錄個(gè)人資料時(shí),確保遵守 GDPR 等法規(guī)。

推薦:

  • 匿名化:刪除或掩蓋日誌中的個(gè)人識(shí)別碼。
  • 存取控制:限制對(duì)日誌檔案的存取。
  • 資料保留策略:定義日誌的儲(chǔ)存時(shí)間。

外部參考:

  • 歐盟 GDPR 合規(guī)性
  • HIPAA 安全規(guī)則

6.利用現(xiàn)有的日誌庫(kù)

有時(shí),使用完善的日誌庫(kù)可以節(jié)省時(shí)間並提供額外的功能。

zlog簡(jiǎn)介:

zlog 是一個(gè)可靠、執(zhí)行緒安全且高度可設(shè)定的 C 日誌庫(kù)。

特徵:

  • 透過(guò)檔案進(jìn)行設(shè)定。
  • 支援多種日誌類別和等級(jí)。
  • 非同步日誌記錄功能。

使用範(fàn)例:

  1. 安裝:
#include "logger.h"

void log_message(const char* text) {
    if (!text) {
        fprintf(stderr, "Invalid log message\n");
        return;
    }
    time_t now = time(NULL);
    printf("[%s] %s\n", ctime(&now), text);
}
  1. 設(shè)定檔(zlog.conf):
#include "logger.h"

int main() {
    log_message("Application started");
    log_message("Performing operation...");
    log_message("Operation completed.");
    return 0;
}
  1. 實(shí)作(main.c):
gcc -o app main.c logger.c
./app
  1. 編譯並執(zhí)行:
[Mon Sep 27 14:00:00 2021
] Application started
[Mon Sep 27 14:00:00 2021
] Performing operation...
[Mon Sep 27 14:00:00 2021
] Operation completed.

外部參考:

  • zlog官方網(wǎng)站
  • log4c 項(xiàng)目

與自訂實(shí)作的比較:

  • 使用圖書館的優(yōu)點(diǎn):

    • 節(jié)省開發(fā)時(shí)間。
    • 提供進(jìn)階功能。
    • 經(jīng)過(guò)充分測(cè)試和維護(hù)。
  • 缺點(diǎn):

    • 可能包含不必要的功能。
    • 新增外部相依性。
    • 對(duì)內(nèi)部運(yùn)作的控制較少。

7. 加強(qiáng)結(jié)論

最後,讓我們強(qiáng)化關(guān)鍵要點(diǎn)並鼓勵(lì)進(jìn)一步探索。

最後的想法:

建立強(qiáng)大的日誌系統(tǒng)是軟體開發(fā)的關(guān)鍵面向。透過(guò)專注於程式碼一致性、錯(cuò)誤處理、清晰度、測(cè)試、安全性並在適當(dāng)?shù)臅r(shí)候利用現(xiàn)有工具,您可以為增強(qiáng)應(yīng)用程式的可維護(hù)性和可靠性奠定基礎(chǔ)。

號(hào)召性用語(yǔ):

  • 應(yīng)用概念:將這些增強(qiáng)功能整合到您的專案中。
  • 進(jìn)一步探索: 研究更高級(jí)的日誌記錄功能,例如日誌輪換、過(guò)濾和分析工具。
  • 保持更新:隨時(shí)了解日誌記錄和軟體開發(fā)方面的最佳實(shí)踐和新興技術(shù)。

其他資源:

  • 日誌記錄的藝術(shù)

以上是用 C 建立健壯的日誌系統(tǒng)的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

c多態(tài)性:功能是否超載一種多態(tài)性? c多態(tài)性:功能是否超載一種多態(tài)性? Jun 20, 2025 am 12:05 AM

是的,函數(shù)重載是C 中的一種多態(tài)形式,具體來(lái)說(shuō)是編譯時(shí)多態(tài)。 1.函數(shù)重載允許使用相同名稱但不同參數(shù)列表的多個(gè)函數(shù)。 2.編譯器根據(jù)提供的參數(shù)在編譯時(shí)決定調(diào)用哪個(gè)函數(shù)。 3.與運(yùn)行時(shí)多態(tài)不同,函數(shù)重載在運(yùn)行時(shí)沒(méi)有額外開銷,實(shí)現(xiàn)簡(jiǎn)單,但靈活性較低。

C中有哪種多態(tài)性的多態(tài)性?解釋了 C中有哪種多態(tài)性的多態(tài)性?解釋了 Jun 20, 2025 am 12:08 AM

C 有兩種主要的多態(tài)類型:編譯時(shí)多態(tài)和運(yùn)行時(shí)多態(tài)。 1.編譯時(shí)多態(tài)通過(guò)函數(shù)重載和模板實(shí)現(xiàn),提供高效但可能導(dǎo)致代碼膨脹。 2.運(yùn)行時(shí)多態(tài)通過(guò)虛函數(shù)和繼承實(shí)現(xiàn),提供靈活性但有性能開銷。

C:多態(tài)性真的有用嗎? C:多態(tài)性真的有用嗎? Jun 20, 2025 am 12:01 AM

是的,C 中的多態(tài)性非常有用。1)它提供了靈活性,允許輕松添加新類型;2)促進(jìn)代碼重用,減少重復(fù);3)簡(jiǎn)化維護(hù),使代碼更易擴(kuò)展和適應(yīng)變化。盡管存在性能和內(nèi)存管理的挑戰(zhàn),但其優(yōu)勢(shì)在復(fù)雜系統(tǒng)中尤為顯著。

C驅(qū)動(dòng)器:常見錯(cuò)誤 C驅(qū)動(dòng)器:常見錯(cuò)誤 Jun 20, 2025 am 12:12 AM

C destructorscanleadtoseveralcommonerrors.Toavoidthem:1)Preventdoubledeletionbysettingpointerstonullptrorusingsmartpointers.2)Handleexceptionsindestructorsbycatchingandloggingthem.3)Usevirtualdestructorsinbaseclassesforproperpolymorphicdestruction.4

C中的多態(tài)性:綜合指南 C中的多態(tài)性:綜合指南 Jun 21, 2025 am 12:11 AM

C 中的多態(tài)性分為運(yùn)行時(shí)多態(tài)性和編譯時(shí)多態(tài)性。 1.運(yùn)行時(shí)多態(tài)性通過(guò)虛函數(shù)實(shí)現(xiàn),允許在運(yùn)行時(shí)動(dòng)態(tài)調(diào)用正確的方法。 2.編譯時(shí)多態(tài)性通過(guò)函數(shù)重載和模板實(shí)現(xiàn),提供更高的性能和靈活性。

c認(rèn)識(shí)python的人的教程 c認(rèn)識(shí)python的人的教程 Jul 01, 2025 am 01:11 AM

學(xué)Python的人轉(zhuǎn)學(xué)C 最直接的困惑是:為什麼不能像Python那樣寫?因?yàn)镃 雖然語(yǔ)法更複雜,但提供了底層控制能力和性能優(yōu)勢(shì)。 1.語(yǔ)法結(jié)構(gòu)上,C 使用花括號(hào){}而非縮進(jìn)組織代碼塊,且變量類型必須顯式聲明;2.類型系統(tǒng)與內(nèi)存管理方面,C 沒(méi)有自動(dòng)垃圾回收機(jī)制,需手動(dòng)管理內(nèi)存並註意釋放資源,使用RAII技術(shù)可輔助資源管理;3.函數(shù)與類定義中,C 需要明確訪問(wèn)修飾符、構(gòu)造函數(shù)和析構(gòu)函數(shù),並支持如運(yùn)算符重載等高級(jí)功能;4.標(biāo)準(zhǔn)庫(kù)方面,STL提供了強(qiáng)大的容器和算法,但需要適應(yīng)泛型編程思想;5

C中的多態(tài)性的各種形式是什麼? C中的多態(tài)性的各種形式是什麼? Jun 20, 2025 am 12:21 AM

C polymorphismincludescompile-time,runtime,andtemplatepolymorphism.1)Compile-timepolymorphismusesfunctionandoperatoroverloadingforefficiency.2)Runtimepolymorphismemploysvirtualfunctionsforflexibility.3)Templatepolymorphismenablesgenericprogrammingfo

C多態(tài)性:編碼樣式 C多態(tài)性:編碼樣式 Jun 19, 2025 am 12:25 AM

C polymorphismisuniqueduetoitscombinationofcompile-timeandruntimepolymorphism,allowingforbothefficiencyandflexibility.Toharnessitspowerstylishly:1)Usesmartpointerslikestd::unique_ptrformemorymanagement,2)Ensurebaseclasseshavevirtualdestructors,3)Emp

See all articles