欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

剖析c/c++的findcontours崩潰完美解決方案

 更新時(shí)間:2025年05月22日 09:32:58   作者:whoarethenext  
許多在Windows平臺(tái)上使用OpenCV的開(kāi)發(fā)者可能會(huì)在使用findContours 函數(shù)時(shí),遇到令人頭疼的程序崩潰問(wèn)題,本文將深入剖析此問(wèn)題的潛在原因,并提供一個(gè)更可靠的定制化實(shí)現(xiàn)方案,感興趣的朋友一起看看吧

解決 Windows 平臺(tái) OpenCV findContours 崩潰:一種更穩(wěn)定的方法

許多在 Windows 平臺(tái)上使用 OpenCV 的開(kāi)發(fā)者可能會(huì)在使用 findContours 函數(shù)時(shí),遇到令人頭疼的程序崩潰問(wèn)題。盡管網(wǎng)絡(luò)上流傳著多種解決方案,但它們并非總能根治此問(wèn)題。
當(dāng)時(shí)我也是挨個(gè)排查才找到原來(lái)是findcontours的崩潰,他奔潰的在內(nèi)存上,有些圖不崩潰有些圖必崩潰搞得很莫名其妙,今天就來(lái)講講我的解決方案

常見(jiàn)的“藥方”包括:

  • 修改項(xiàng)目配置:配置屬性 -> 常規(guī) -> 項(xiàng)目默認(rèn)值 -> MFC的使用 -> 在共享DLL中使用MFC;
  • 調(diào)整C/C++代碼生成選項(xiàng):C/C++ -> 代碼生成 -> 運(yùn)行庫(kù) -> 多線(xiàn)程DLL(/MD);
  • 代碼層面規(guī)范:例如 vector 使用 cv::vector,vector<vector<Point>> 聲明時(shí)預(yù)分配空間等。

然而,現(xiàn)實(shí)情況是,許多開(kāi)發(fā)者嘗試上述方法后,問(wèn)題依舊。即便少數(shù)情況下問(wèn)題得到偶然解決,程序在遷移到不同環(huán)境或 OpenCV 版本時(shí),仍可能面臨兼容性風(fēng)險(xiǎn)。

本文將深入剖析此問(wèn)題的潛在原因,并提供一個(gè)更可靠的定制化實(shí)現(xiàn)方案。

探究崩潰的根源

為了有效地解決 findContours 引發(fā)的異常,理解其內(nèi)部機(jī)制至關(guān)重要。cv::findContours 的C++接口實(shí)際上是對(duì)底層C語(yǔ)言風(fēng)格函數(shù) cvFindContours(或其變體 cvFindContours_Impl)的一層封裝。

一個(gè)關(guān)鍵的觀(guān)察點(diǎn)是:直接調(diào)用C語(yǔ)言風(fēng)格的 cvFindContours 函數(shù)往往能夠正常運(yùn)行,這暗示問(wèn)題很可能出在C++封裝層對(duì)數(shù)據(jù)結(jié)構(gòu)的處理上。

仔細(xì)研讀 cv::findContours 的源碼(盡管具體實(shí)現(xiàn)可能隨版本略有差異),我們會(huì)注意到其處理輸出參數(shù) _contours(通常是 std::vector<std::vector<cv::Point>> 類(lèi)型)的方式:

// OpenCV findContours 源碼示意片段
void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
                       OutputArray _hierarchy, int mode, int method, Point offset )
{
    // ... (一系列檢查和準(zhǔn)備工作) ...
    // _contours 的內(nèi)存分配與數(shù)據(jù)填充,示意如下:
    // _contours.create(total, 1, 0, -1, true); // 為所有輪廓的集合分配概要空間
    // ...
    // for( i = 0; i < total; i++, ++it )
    // {
    //     CvSeq* c = *it;
    //     // ...
    //     _contours.create((int)c->total, 1, CV_32SC2, i, true); // 為單個(gè)輪廓分配空間
    //     Mat ci = _contours.getMat(i); // 獲取該輪廓對(duì)應(yīng)的 Mat 頭
    //     cvCvtSeqToArray(c, ci.ptr()); // 將 CvSeq 數(shù)據(jù)拷貝到 Mat 指向的內(nèi)存
    // }
    // ...
}

上述代碼片段揭示了潛在的風(fēng)險(xiǎn)點(diǎn):OpenCV 在為 _contours 分配內(nèi)存時(shí),尤其是后續(xù)通過(guò) _contours.getMat(i) 獲取 Mat 對(duì)象并用 cvCvtSeqToArray 填充數(shù)據(jù)時(shí),它可能對(duì) std::vector<std::vector<cv::Point>> 的內(nèi)部?jī)?nèi)存布局做出了某些假設(shè)。這種直接將 CvSeq 中的數(shù)據(jù)拷貝到由 Mat 管理的內(nèi)存區(qū)域,如果該內(nèi)存區(qū)域未能被 std::vector 正確識(shí)別和管理,就可能導(dǎo)致內(nèi)存損壞。

推測(cè)原因?yàn)椋?/p>

  • _contours.create() 方法可能不完全適用于 std::vector 這種復(fù)雜類(lèi)型的內(nèi)存分配和初始化。
  • std::vector 的數(shù)據(jù)存儲(chǔ)并非總是能被簡(jiǎn)單地視為一塊連續(xù)內(nèi)存區(qū)域,并允許通過(guò)外部指針直接進(jìn)行填充,特別是對(duì)于嵌套的 vector。

這種不匹配的操作極易破壞 std::vector 的內(nèi)部狀態(tài),最終導(dǎo)致程序在后續(xù)訪(fǎng)問(wèn)這些輪廓數(shù)據(jù)時(shí)發(fā)生崩潰。

更穩(wěn)健的解決方案:自定義封裝 cvFindContours

既然底層的 cvFindContours 函數(shù)相對(duì)穩(wěn)定,那么我們可以繞過(guò) cv::findContours 中可能存在問(wèn)題的內(nèi)存操作,通過(guò)重新封裝 cvFindContours 來(lái)實(shí)現(xiàn)一個(gè)更安全、更可控的輪廓查找函數(shù)。

以下是提供的自定義 findContours 函數(shù)實(shí)現(xiàn),它直接調(diào)用C接口并手動(dòng)管理 std::vector 的數(shù)據(jù)填充:

#include <opencv2/opencv.hpp> // 根據(jù)需要包含具體的頭文件,如 imgproc.hpp, core.hpp
#include <vector>
// 注意:此函數(shù)簽名和實(shí)現(xiàn)源自您提供的原始代碼
void findContours_custom(const cv::Mat& src,
                         std::vector<std::vector<cv::Point>>& contours,
                         std::vector<cv::Vec4i>& hierarchy,
                         int retr,
                         int method,
                         cv::Point offset = cv::Point())
{
    contours.clear(); // 清空輸出
    hierarchy.clear();
// 根據(jù)OpenCV版本處理CvMat,您提供的代碼片段如下:
#if CV_VERSION_REVISION <= 6 // 注意:CV_VERSION_REVISION 是較老版本OpenCV的宏
    CvMat c_image = src; // 在舊版本中,cv::Mat可以直接轉(zhuǎn)換為CvMat
                         // 但請(qǐng)注意,cvFindContours可能會(huì)修改圖像,所以最好使用副本
                         // CvMat c_image = src.clone(); 這樣更安全
#else
    // 對(duì)于較新的OpenCV版本 (3.x, 4.x)
    cv::Mat mutable_src = src.clone(); // cvFindContours會(huì)修改輸入圖像,務(wù)必使用副本
    CvMat c_image = cvMat(mutable_src.rows, mutable_src.cols, mutable_src.type(), mutable_src.data);
    c_image.step = static_cast<int>(mutable_src.step[0]); // 顯式轉(zhuǎn)換size_t到int
    c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (mutable_src.flags & cv::Mat::CONTINUOUS_FLAG);
#endif
    cv::MemStorage storage(cvCreateMemStorage(0)); // 創(chuàng)建內(nèi)存存儲(chǔ)區(qū)
    CvSeq* _ccontours = nullptr; // C風(fēng)格的輪廓序列指針
// 根據(jù)OpenCV版本調(diào)用cvFindContours,您提供的代碼片段如下:
#if CV_VERSION_REVISION <= 6
    cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, cvPoint(offset.x, offset.y));
#else
    cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, cvPoint(offset.x, offset.y)); // CvPoint構(gòu)造方式一致
#endif
    if (!_ccontours) // 如果沒(méi)有找到輪廓
    {
        contours.clear(); // 再次確保清空
        hierarchy.clear();
        // storage 會(huì)在 cv::MemStorage 對(duì)象析構(gòu)時(shí)自動(dòng)釋放
        return;
    }
    // 使用 cvTreeToNodeSeq 獲取所有輪廓的扁平序列,這對(duì)于后續(xù)處理(尤其是層級(jí)結(jié)構(gòu))更方便
    cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
    size_t total = all_contours.size();
    contours.resize(total); // 為輪廓數(shù)據(jù)預(yù)分配空間
    hierarchy.resize(total); // 為層級(jí)數(shù)據(jù)預(yù)分配空間
    cv::SeqIterator<CvSeq*> it = all_contours.begin();
    for (size_t i = 0; i < total; ++i, ++it)
    {
        CvSeq* c = *it;
        // 將輪廓的顏色(CvContour的成員)設(shè)置為其索引,用于后續(xù)層級(jí)信息的鏈接
        reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
        int count = c->total; // 當(dāng)前輪廓包含的點(diǎn)數(shù)
        if (count > 0) {
            // 您提供的原始代碼中使用 new int[] 來(lái)中轉(zhuǎn)點(diǎn)坐標(biāo)
            int* data = new int[static_cast<size_t>(count * 2)]; // 分配臨時(shí)內(nèi)存存儲(chǔ)x,y坐標(biāo)對(duì)
            cvCvtSeqToArray(c, data, CV_WHOLE_SEQ); // 將CvSeq中的點(diǎn)集數(shù)據(jù)拷貝到data數(shù)組
            contours[i].reserve(count); // 為當(dāng)前輪廓的點(diǎn)集預(yù)分配空間
            for (int j = 0; j < count; ++j) {
                contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
            }
            delete[] data; // 釋放臨時(shí)內(nèi)存
        }
    }
    // 填充層級(jí)信息 (hierarchy)
    it = all_contours.begin(); // 重置迭代器
    for (size_t i = 0; i < total; ++i, ++it)
    {
        CvSeq* c = *it;
        // 通過(guò)之前設(shè)置的 color (即索引) 來(lái)獲取層級(jí)關(guān)系
        int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
        int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
        int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1; // 第一個(gè)子輪廓
        int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1; // 父輪廓
        hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
    }
    // storage 會(huì)在 cv::MemStorage 對(duì)象析構(gòu)時(shí)自動(dòng)釋放,無(wú)需顯式調(diào)用 cvReleaseMemStorage
}

自定義函數(shù)的關(guān)鍵改進(jìn)點(diǎn):

  • 直接調(diào)用C接口:函數(shù)核心是調(diào)用 cvFindContours,避免了C++封裝層中可疑的內(nèi)存操作。
  • 安全的內(nèi)存管理:使用 cv::MemStorage 為C函數(shù)管理內(nèi)存。
  • 顯式數(shù)據(jù)轉(zhuǎn)換與填充
    • 通過(guò) cvTreeToNodeSeq 獲取所有輪廓的扁平列表,這簡(jiǎn)化了迭代和層級(jí)構(gòu)建。
    • std::vector<std::vector<cv::Point>> contoursstd::vector<cv::Vec4i> hierarchy 調(diào)用 resize 進(jìn)行預(yù)分配。
    • 對(duì)于每個(gè) CvSeq,您的原始方案是先用 cvCvtSeqToArray 將點(diǎn)數(shù)據(jù)讀入一個(gè)臨時(shí)的 int 數(shù)組 data,然后再遍歷這個(gè) data 數(shù)組,逐點(diǎn)構(gòu)造 cv::Point 對(duì)象并 push_back 到對(duì)應(yīng)的 contours[i] 中。
    • 這種方式雖然多了一步中轉(zhuǎn),但確保了 std::vector 完全自主地管理其元素的內(nèi)存。
  • 層級(jí)信息構(gòu)建:通過(guò)在第一次遍歷輪廓時(shí)將 CvContourcolor 成員設(shè)置為其在 all_contours序列中的索引,然后在第二次遍歷時(shí)利用這個(gè)索引來(lái)正確構(gòu)建 hierarchy 向量。

這種方法雖然代碼量稍多,但給予了開(kāi)發(fā)者對(duì)內(nèi)存操作更大的控制權(quán),從而有效規(guī)避了標(biāo)準(zhǔn) cv::findContours C++ 接口在特定情況下可能引發(fā)的內(nèi)存問(wèn)題。

測(cè)試用例

下面是一個(gè)使用上述 findContours_custom 函數(shù)的C++示例程序。

test_custom_findcontours_cn.cpp:

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/types_c.h>    // 為了 CvMat, CvSeq 等C語(yǔ)言結(jié)構(gòu)
#include <opencv2/imgproc/types_c.h> // 為了 CV_*, CvContour, CvPoint 等
#include <iostream>
#include <vector>
// --- [粘貼上面提供的 findContours_custom 函數(shù)代碼到這里] ---
void findContours_custom(const cv::Mat& src,
                         std::vector<std::vector<cv::Point>>& contours,
                         std::vector<cv::Vec4i>& hierarchy,
                         int retr,
                         int method,
                         cv::Point offset = cv::Point())
{
    contours.clear();
    hierarchy.clear();
#if CV_VERSION_REVISION <= 6
    cv::Mat mutable_src_for_c_api = src.clone(); // 為舊版API準(zhǔn)備可修改的副本
    CvMat c_image = mutable_src_for_c_api;
#else
    cv::Mat mutable_src_for_c_api = src.clone();
    CvMat c_image = cvMat(mutable_src_for_c_api.rows, mutable_src_for_c_api.cols, mutable_src_for_c_api.type(), mutable_src_for_c_api.data);
    c_image.step = static_cast<int>(mutable_src_for_c_api.step[0]);
    c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (mutable_src_for_c_api.flags & cv::Mat::CONTINUOUS_FLAG);
#endif
    cv::MemStorage storage(cvCreateMemStorage(0));
    CvSeq* _ccontours = nullptr;
#if CV_VERSION_REVISION <= 6
    cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, cvPoint(offset.x, offset.y));
#else
    cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, cvPoint(offset.x, offset.y));
#endif
    if (!_ccontours)
    {
        contours.clear();
        hierarchy.clear();
        return;
    }
    cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
    size_t total = all_contours.size();
    contours.resize(total);
    hierarchy.resize(total);
    cv::SeqIterator<CvSeq*> it = all_contours.begin();
    for (size_t i = 0; i < total; ++i, ++it)
    {
        CvSeq* c = *it;
        reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
        int count = c->total;
        if (count > 0) {
            int* data = new int[static_cast<size_t>(count * 2)];
            cvCvtSeqToArray(c, data, CV_WHOLE_SEQ);
            contours[i].reserve(count);
            for (int j = 0; j < count; ++j) {
                contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
            }
            delete[] data;
        }
    }
    it = all_contours.begin();
    for (size_t i = 0; i < total; ++i, ++it)
    {
        CvSeq* c = *it;
        int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
        int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
        int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
        int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
        hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
    }
}
// --- [findContours_custom 函數(shù)代碼結(jié)束] ---
int main() {
    // 1. 創(chuàng)建一個(gè)示例二值圖像
    cv::Mat image = cv::Mat::zeros(300, 300, CV_8UC1); // 黑色背景
    // 繪制一個(gè)白色外層矩形
    cv::rectangle(image, cv::Rect(30, 30, 240, 240), cv::Scalar(255), cv::FILLED);
    // 在外層矩形內(nèi)部繪制一個(gè)黑色矩形(形成一個(gè)“洞”)
    cv::rectangle(image, cv::Rect(80, 80, 140, 140), cv::Scalar(0), cv::FILLED);
    // 再繪制一個(gè)獨(dú)立的白色小矩形
    cv::rectangle(image, cv::Rect(10, 10, 50, 50), cv::Scalar(255), cv::FILLED);
    if (image.empty()) {
        std::cerr << "錯(cuò)誤:無(wú)法創(chuàng)建示例圖像。" << std::endl;
        return -1;
    }
    // 2. 準(zhǔn)備輸出容器
    std::vector<std::vector<cv::Point>> contours_vec;
    std::vector<cv::Vec4i> hierarchy_vec;
    // 3. 調(diào)用自定義的 findContours_custom 函數(shù)
    // 使用 cv::RETR_TREE 來(lái)測(cè)試層級(jí)結(jié)構(gòu)
    findContours_custom(image, contours_vec, hierarchy_vec, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
    // 4. 輸出結(jié)果
    std::cout << "自定義函數(shù)找到的輪廓數(shù)量: " << contours_vec.size() << std::endl;
    for (size_t i = 0; i < contours_vec.size(); ++i) {
        std::cout << "輪廓 #" << i << ": " << contours_vec[i].size() << " 個(gè)點(diǎn). ";
        std::cout << "層級(jí)信息: " << hierarchy_vec[i] << std::endl;
    }
    // 5. 可選: 顯示結(jié)果圖像
    cv::Mat contour_output_image = cv::Mat::zeros(image.size(), CV_8UC3);
    cv::RNG rng(12345); // 用于生成隨機(jī)顏色
    for (size_t i = 0; i < contours_vec.size(); i++) {
        // 為每個(gè)輪廓隨機(jī)選擇一種顏色
        cv::Scalar color = cv::Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
        // 繪制輪廓
        cv::drawContours(contour_output_image, contours_vec, (int)i, color, 2, cv::LINE_8, hierarchy_vec, 0);
    }
    cv::imshow("原始測(cè)試圖像", image);
    cv::imshow("檢測(cè)到的輪廓 (自定義函數(shù))", contour_output_image);
    cv::waitKey(0); // 等待按鍵
    return 0;
}

編譯和運(yùn)行示例 (使用g++):

g++ test_custom_findcontours_cn.cpp -o test_custom_findcontours_cn $(pkg-config --cflags --libs opencv4)
./test_custom_findcontours_cn

(如果你的 OpenCV 版本不是4,或者 pkg-config 未正確配置,請(qǐng)相應(yīng)調(diào)整 opencv4opencv 或你的實(shí)際庫(kù)名和路徑)。

此測(cè)試用例會(huì)創(chuàng)建一個(gè)包含嵌套結(jié)構(gòu)的簡(jiǎn)單圖像,調(diào)用 findContours_custom 函數(shù),打印檢測(cè)到的輪廓數(shù)量及其層級(jí)信息,并最終將檢測(cè)結(jié)果可視化顯示。在之前可能導(dǎo)致崩潰的 Windows 環(huán)境下,此自定義函數(shù)應(yīng)該能夠穩(wěn)定運(yùn)行。

通過(guò)采用這種自定義封裝策略,開(kāi)發(fā)者可以更從容地應(yīng)對(duì) OpenCV 在特定平臺(tái)下可能出現(xiàn)的穩(wěn)定性問(wèn)題,確保輪廓檢測(cè)功能的可靠性。

到此這篇關(guān)于c/c++的findcontours崩潰解決方案的文章就介紹到這了,更多相關(guān)c++ findcontours崩潰內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

  • 原創(chuàng)的C語(yǔ)言控制臺(tái)小游戲

    原創(chuàng)的C語(yǔ)言控制臺(tái)小游戲

    本文給大家分享的是個(gè)人原創(chuàng)設(shè)計(jì)的一個(gè)C語(yǔ)言控制臺(tái)小游戲,非常的簡(jiǎn)單,但是挺好玩的,推薦給大家,有需要的小伙伴也可以自由擴(kuò)展下。
    2015-03-03
  • 利用上下文屬性將?C++?對(duì)象嵌入?QML?里

    利用上下文屬性將?C++?對(duì)象嵌入?QML?里

    這篇文章主要介紹了利用上下文屬性將?C++?對(duì)象嵌入?QML里,將?QML?對(duì)象加載到?C++?應(yīng)用程序中時(shí),直接嵌入一些可在?QML?代碼中使用的?C++?數(shù)據(jù)會(huì)很有用。例如,這使得在嵌入對(duì)象上調(diào)用?C++?方法或使用?C++?對(duì)象實(shí)例作為?QML?視圖的數(shù)據(jù)模型成為可能,下面一起來(lái)學(xué)習(xí)該內(nèi)容吧
    2021-12-12
  • C++排序算法之冒泡排序解析

    C++排序算法之冒泡排序解析

    這篇文章主要介紹了C++排序算法之冒泡排序解析,從左到右,相鄰兩數(shù)兩兩比較,若下標(biāo)小的數(shù)大于下標(biāo)大的數(shù)則交換,將最大的數(shù)放在數(shù)組的最后一位,,再次遍歷數(shù)組,將第二大的數(shù),放在數(shù)組倒數(shù)第二的位置,以此類(lèi)推,直到數(shù)組有序需要的朋友可以參考下
    2023-10-10
  • Qt 使用Poppler實(shí)現(xiàn)pdf閱讀器的示例代碼

    Qt 使用Poppler實(shí)現(xiàn)pdf閱讀器的示例代碼

    下面小編就為大家分享一篇Qt 使用Poppler實(shí)現(xiàn)pdf閱讀器的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • C語(yǔ)言通訊錄管理系統(tǒng)課程設(shè)計(jì)

    C語(yǔ)言通訊錄管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言通訊錄管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C++新特性詳細(xì)分析基于范圍的for循環(huán)

    C++新特性詳細(xì)分析基于范圍的for循環(huán)

    C++11這次的更新帶來(lái)了令很多C++程序員期待已久的for?range循環(huán),每次看到j(luò)avascript,?lua里的for?range,心想要是C++能有多好,心里別提多酸了。這次C++11不負(fù)眾望,再也不用羨慕別家人的for?range了。下面看下C++11的for循環(huán)的新用法
    2022-04-04
  • C++超詳細(xì)講解拷貝構(gòu)造函數(shù)

    C++超詳細(xì)講解拷貝構(gòu)造函數(shù)

    我們經(jīng)常會(huì)用一個(gè)變量去初始化一個(gè)同類(lèi)型的變量,那么對(duì)于自定義的類(lèi)型也應(yīng)該有類(lèi)似的操作,那么創(chuàng)建對(duì)象時(shí)如何使用一個(gè)已經(jīng)存在的對(duì)象去創(chuàng)建另一個(gè)與之相同的對(duì)象呢
    2022-06-06
  • 解析C語(yǔ)言結(jié)構(gòu)體及位段

    解析C語(yǔ)言結(jié)構(gòu)體及位段

    今天小編就為大家分享一篇關(guān)于解析C語(yǔ)言結(jié)構(gòu)體及位段,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • 最新評(píng)論