中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

做介紹美食網(wǎng)站的菜單的企業(yè)seo整站優(yōu)化方案

做介紹美食網(wǎng)站的菜單的,企業(yè)seo整站優(yōu)化方案,新疆建設(shè)廳官網(wǎng)查詢(xún),簡(jiǎn)單的美食網(wǎng)站模板免費(fèi)下載單例九品--第五品 上一品引入寫(xiě)在前邊代碼部分1代碼部分2實(shí)現(xiàn)方式評(píng)注與思考下一品的設(shè)計(jì)思考 上一品引入 第四品中可能會(huì)因?yàn)榉g單元的鏈接先后順序,造成靜態(tài)初始化災(zāi)難的問(wèn)題。造成的原因是因?yàn)榇嬖谡{(diào)用單例對(duì)象前沒(méi)有完成定義的問(wèn)題,這一品將著重解…

單例九品--第五品

  • 上一品引入
  • 寫(xiě)在前邊
  • 代碼部分1
  • 代碼部分2
  • 實(shí)現(xiàn)方式評(píng)注與思考
  • 下一品的設(shè)計(jì)思考

上一品引入

第四品中可能會(huì)因?yàn)榉g單元的鏈接先后順序,造成靜態(tài)初始化災(zāi)難的問(wèn)題。造成的原因是因?yàn)榇嬖谡{(diào)用單例對(duì)象前沒(méi)有完成定義的問(wèn)題,這一品將著重解決這個(gè)問(wèn)題。

寫(xiě)在前邊

  • 基本思路
    ? 引入初始化類(lèi)
    ? 初始化類(lèi)是單例類(lèi)的子類(lèi),可以訪問(wèn)單例類(lèi)的所有成員
    ? 通過(guò)初始化類(lèi)的實(shí)例作為紐帶,一定程度上控制初始化順序
  • 優(yōu)點(diǎn)
    ? 初始化類(lèi)可以精確控制初始化時(shí)機(jī)
  • 缺點(diǎn)
    ? 似乎可以解決 static initialization order fiasco 問(wèn)題,但實(shí)際上程序包含了更深層次的
    隱患:可能出現(xiàn)未定義的行為

代碼部分1

三個(gè)文件: main.cpp, sing.cpp和sing.h

  • main.cpp
#include "sing.h"static Sing::Init init; auto singletonInst2 = singletonInst->val;int main(int argc, char** argv)
{std::cout << "get value: " << singletonInst2 << '\n';
}
  • sing.cpp
#include "sing.h"
#include <memory>
#include <iostream>std::unique_ptr<Sing> singletonInst;Sing::Init::Init()
{if (!singletonInst){singletonInst.reset(new Sing()); }
}
  • sing.h
#pragma once
#include <iostream>
#include <memory>class Sing
{
public:struct Init{Init();Init(const Init&) = delete;Init& operator= (const Init&) = delete;};public:~Sing(){std::cout << "Sing destroy\n";}private:Sing(){std::cout << "Sing construct\n";val = 100;}Sing(const Sing&) = delete;Sing& operator= (const Sing&) = delete;
public:int val;
};extern std::unique_ptr<Sing> singletonInst; // 聲明,把sing.cpp中的定義暴露給main.cpp// init為sing類(lèi)的子類(lèi)
  • output

編譯鏈接運(yùn)行方式1
g++ -c ./main.cpp -std=c++20 (-std參數(shù)可選)
g++ -c ./sing.cpp -std=c++20 (-std參數(shù)可選)
g++ main.o sing.o -o ./ms
./ms

Sing construct
get value: 100
Sing destroy

編譯鏈接運(yùn)行方式2
g++ -c ./main.cpp -std=c++20 (-std參數(shù)可選)
g++ -c ./sing.cpp -std=c++20 (-std參數(shù)可選)
g++ sing.o main.o -o ./sm
./sm

Sing construct
get value: 100
Sing destroy

從上邊結(jié)果可以看出,無(wú)論什么樣的鏈接順序,都可以正常運(yùn)行,那是不是這種實(shí)現(xiàn)方式已經(jīng)完全沒(méi)有問(wèn)題了? 不是的,下邊的變種將會(huì)說(shuō)明這一點(diǎn)!!!

代碼部分2

三個(gè)文件: main.cpp sing.cpp 和sing.h

  • main.cpp
#include "sing.h"static Sing::Init init;
auto singletonInst2 = singletonInst->val;int main(int argc, char** argv)
{std::cout << "get value: " << singletonInst2 << '\n';std::cout << singletonInst.get() << std::endl;std::cout << singletonInst->val << std::endl;return 0;
}
  • sing.cpp
#include "sing.h"
#include <memory>
#include <iostream>MyUniquePtr<Sing> singletonInst;Sing::Init::Init()
{if (!singletonInst){singletonInst.reset(new Sing());}
}
  • sing.h
#pragma once
#include <iostream>
#include <memory>class Sing
{
public:struct Init{Init();Init(const Init&) = delete;Init& operator= (const Init&) = delete;};public:~Sing(){std::cout << "Sing destroy\n";}private:Sing(){std::cout << "Sing construct\n";val = 100;}Sing(const Sing&) = delete;Sing& operator= (const Sing&) = delete;
public:int val;
};template <typename T>
class MyUniquePtr : public std::unique_ptr<T>
{
public:MyUniquePtr() : std::unique_ptr<T>() {}
};extern MyUniquePtr<Sing> singletonInst;
  • output

編譯鏈接運(yùn)行方式1:
g++ -c ./main.cpp
g++ -c ./sing.cpp
g++ main.o sing.o -o ./ms

Sing construct
get value: 100
0
Segmentation fault (core dumped)  段錯(cuò)誤

編譯鏈接運(yùn)行方式2:
g++ -c ./main.cpp
g++ -c ./sing.cpp
g++ sing.o main.o -o ./sm

Sing construct
get value: 100
0x56457bcd1eb0
100
Sing destroy

這個(gè)例子與上一個(gè)例子的實(shí)現(xiàn)方式是一致的,不同點(diǎn)在于單例對(duì)象的類(lèi)型不同,前者對(duì)象是unique_ptr類(lèi)型,后者是unique_ptr的派生類(lèi)型。然而就是因?yàn)槭褂昧藆nique_ptr的派生類(lèi)型MyUniquePtr,就出現(xiàn)了鏈接的時(shí)候翻譯單元main.cpp在前,sing.cpp在后時(shí),出現(xiàn)了單例調(diào)用前未定義的問(wèn)題。

這是什么原因吶?
在解釋這個(gè)問(wèn)題之前需要明白不同類(lèi)型對(duì)象的初始化時(shí)間和初始化類(lèi)型,在這里辨析編譯期初始化,零初始化和缺省初始化的區(qū)別:

  1. 編譯期初始化: c++中常見(jiàn)的編譯器初始化包括但不限于常量表達(dá)式(constexpr, 凡是被constexpr修飾的函數(shù)和變量,都可以在編譯期實(shí)現(xiàn)初始化,但是具體也要取決于編譯器的類(lèi)型,因?yàn)橛行┚幾g器會(huì)選擇在運(yùn)行初始化constexpr),枚舉類(lèi)型enum和模板元編程等。也就是在編譯期就完成了計(jì)算,并將對(duì)應(yīng)的結(jié)果存起來(lái),在運(yùn)行期的時(shí)候直接使用。
    編譯期初始化,分為兩種,constexpr和consteval,constexpr修飾的函數(shù),意思是可以在編譯期被調(diào)用,也可以選在在運(yùn)行期被調(diào)用,但是具體什么時(shí)候被調(diào)用,是取決于使用的編譯器種類(lèi)consteval修飾的函數(shù),意思是可以編譯器被調(diào)用,并且必須在編譯期調(diào)用。如果定義一個(gè)實(shí)例對(duì)象,這個(gè)對(duì)象的構(gòu)造函數(shù)被consteval修飾,那么一定在編譯期系統(tǒng)就會(huì)計(jì)算出這個(gè)對(duì)象的值存起來(lái),在運(yùn)行的時(shí)候直接完成兩者的聯(lián)系。

  2. 零初始化: 指在變量聲明時(shí)將其初始化為零或默認(rèn)值的行為。在C++中,如果沒(méi)有顯式提供初始化值,那么內(nèi)置類(lèi)型的變量將被初始化為零,而自定義類(lèi)型的變量將調(diào)用其默認(rèn)構(gòu)造函數(shù)進(jìn)行初始化。

  3. 缺省初始化: 缺省初始化與零初始化在自定義類(lèi)型上的行為一致,也會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù)來(lái)初始化成員變量。如果成員變量沒(méi)有在構(gòu)造函數(shù)中顯式初始化,那么它們將保持未定義的狀態(tài)。

運(yùn)行期初始化與編譯期初始化
對(duì)于在運(yùn)行期才初始化的對(duì)象,采用的初始化方式是零初始化和缺省初始化。在編譯的時(shí)候,系統(tǒng)首先計(jì)算這個(gè)對(duì)象所需的內(nèi)存空間,然后將這塊內(nèi)存里邊的所有內(nèi)容都改為0,這就完成了零初始化的過(guò)程,也就是說(shuō)這個(gè)實(shí)例對(duì)象指向了內(nèi)容全為0的一塊內(nèi)存A。隨后在運(yùn)行的時(shí)候,當(dāng)輪到該對(duì)象的定義初始化的時(shí)候,然后進(jìn)行該對(duì)象的缺省初始化,缺省初始化會(huì)讓該對(duì)象指向懸空,也就是指針P沒(méi)有具體的指向區(qū)域,是個(gè)還沒(méi)有分配指向的空指針。

例子2中,如果鏈接的時(shí)候main.o在前,sing.o在后。因?yàn)閟inglentonInst的類(lèi)型是unique_ptr的拓展類(lèi),構(gòu)造函數(shù)不是constexpr類(lèi)型的(因此是運(yùn)行期初始化,進(jìn)行零初始化和缺省初始化的操作)。所以編譯器首先完成了sing.cpp中的對(duì)象singlentoninst的零初始化,也就是是這個(gè)對(duì)象指向一開(kāi)內(nèi)存都是0的空間。然后在mian.cpp中調(diào)用init,使得對(duì)象singlentonInst指向一塊新的有內(nèi)容的區(qū)域(其中有val=100)。然后進(jìn)入sing.o完成singlentonInst的缺省初始化,使得對(duì)象懸空(未定義,指針未分配),所以指向?yàn)榭?0),輸出singletonInst->val的時(shí)候出現(xiàn)段錯(cuò)誤。

例子1不會(huì)因?yàn)殒溄禹樞虺鰡?wèn)題是因?yàn)槌橄箢?lèi)型unique_ptr的默認(rèn)構(gòu)造函數(shù)被constexpr修飾,g++編譯默認(rèn)constexpr類(lèi)型構(gòu)造函數(shù)在編譯期被調(diào)用,實(shí)現(xiàn)了對(duì)象的編譯期初始化。
在這里插入圖片描述

實(shí)現(xiàn)方式評(píng)注與思考

  1. 對(duì)于在運(yùn)行期才初始化的對(duì)象,采用的初始化方式是零初始化和缺省初始化。在編譯的時(shí)候,系統(tǒng)首先計(jì)算這個(gè)對(duì)象所需的內(nèi)存空間,然后將這塊內(nèi)存里邊的所有內(nèi)容都改為0,這就完成了零初始化的過(guò)程,也就是說(shuō)這個(gè)實(shí)例對(duì)象指向了內(nèi)容全為0的一塊內(nèi)存A。隨后在運(yùn)行的時(shí)候,當(dāng)輪到該對(duì)象的定義初始化的時(shí)候,然后進(jìn)行該對(duì)象的缺省初始化,缺省初始化會(huì)讓該對(duì)象指向懸空,也就是指針P沒(méi)有具體的指向區(qū)域,是個(gè)還沒(méi)有分配指向的空指針。

  2. 實(shí)現(xiàn)方式2與1的區(qū)別就在于使用的對(duì)象類(lèi)型是unique_ptr的派生類(lèi)型,因?yàn)檫@個(gè)派生的指針類(lèi)型構(gòu)造函數(shù)不能在編譯器被調(diào)用,所以鏈接的時(shí)候main.o在前,sing.o在后就會(huì)出現(xiàn)sing中對(duì)象缺省初
    初始化的時(shí)候造成了對(duì)象指針懸空。如果要正常運(yùn)行,要么就是在這個(gè)構(gòu)造函數(shù)前加上關(guān)鍵字constexpr(c11后就可以用),或者consteval(C20才能用)。要么就是在sing.cpp中的singletomInst對(duì)象定義后邊就上一句init的調(diào)用。

  3. 為了防止出現(xiàn)第四品中出現(xiàn)的運(yùn)因?yàn)榉g單元main.o鏈接在sing.o前,出現(xiàn)的singletonInst單例未初始化就被調(diào)用造成的靜態(tài)初始化災(zāi)難。通過(guò)引入初始化類(lèi),初始化類(lèi)作為單例類(lèi)的子類(lèi),可以訪問(wèn)單例類(lèi)的所有成員。然后通過(guò)初始化類(lèi)的實(shí)例作為紐帶,一定程度上控制初始化順序。無(wú)論兩個(gè)翻譯單元連接順序誰(shuí)先誰(shuí)后,因unique_ptr和init實(shí)例在調(diào)用singletonInst前邊,就避免了靜態(tài)實(shí)例初始化災(zāi)難

  4. 在C++中,一個(gè)翻譯單元的變量定義順序有規(guī)定,但是不同的翻譯單元的順序沒(méi)有規(guī)定。第四品的問(wèn)題是可能會(huì)出現(xiàn)兩個(gè)翻譯單元鏈接順序先后問(wèn)題造成的靜態(tài)實(shí)例災(zāi)難。在本次實(shí)現(xiàn)1中(編譯器實(shí)現(xiàn)unique_ptr對(duì)象的編譯期初始化的話),就不在依賴(lài)兩個(gè)翻譯單元的鏈接順序。

  5. main.cpp中 初始化類(lèi)的定義 限定為static是因?yàn)樵诖箜?xiàng)目中,可能會(huì)出現(xiàn)其他cpp文件中也用到同樣名字,在鏈接的時(shí)候就會(huì)出錯(cuò)

  6. init是sing類(lèi)的子類(lèi),完整的繼承sing類(lèi)的所有函數(shù),所以在sing.cpp的init函數(shù)構(gòu)造函數(shù)中使用new Sing的時(shí)候可以調(diào)用私有構(gòu)造函數(shù)。

  • 缺點(diǎn):
    這種實(shí)現(xiàn)方式存在未定義的問(wèn)題,即便是實(shí)現(xiàn)1,也會(huì)因?yàn)榫幾g器的不同出現(xiàn)問(wèn)題,如果某個(gè)編譯器沒(méi)有讓constexpr修飾的unique_ptr對(duì)象的構(gòu)造函數(shù)在編譯期被調(diào)用,完成對(duì)象的編譯期初始化,那么也會(huì)出現(xiàn)問(wèn)題。

下一品的設(shè)計(jì)思考

下一品將解決這種因?yàn)殒溄禹樞蛟斐傻奈炊x問(wèn)題。

http://www.risenshineclean.com/news/6345.html

相關(guān)文章:

  • 咋做網(wǎng)站代碼背景圖seo怎樣優(yōu)化網(wǎng)站
  • 網(wǎng)站解析查詢(xún)?nèi)W(wǎng)營(yíng)銷(xiāo)渠道
  • 淮南發(fā)布seo網(wǎng)站優(yōu)化培訓(xùn)公司
  • pa66用途障車(chē)做網(wǎng)站百度應(yīng)用商店下載安裝
  • 東莞公司網(wǎng)站開(kāi)發(fā)武漢網(wǎng)站設(shè)計(jì)十年樂(lè)云seo
  • 個(gè)性化定制網(wǎng)站公司宣傳軟文
  • 三好街做網(wǎng)站的公司百度搜索網(wǎng)站優(yōu)化
  • 如何在本地發(fā)布自己做的網(wǎng)站中國(guó)十大網(wǎng)站排名
  • 2021跨境電商最火的產(chǎn)品西安seo技術(shù)
  • 版式設(shè)計(jì)網(wǎng)站優(yōu)化人員通常會(huì)將目標(biāo)關(guān)鍵詞放在網(wǎng)站首頁(yè)中的
  • 網(wǎng)站集群建設(shè)廣告平臺(tái)
  • 網(wǎng)站查詢(xún)功能怎么做seo咨詢(xún)河北
  • 教育類(lèi)網(wǎng)站模板交換鏈接名詞解釋
  • 創(chuàng)業(yè)網(wǎng)站推廣怎么做seo最新優(yōu)化技術(shù)
  • 在網(wǎng)盤(pán)上怎么做自己的網(wǎng)站太原網(wǎng)站開(kāi)發(fā)
  • 網(wǎng)站開(kāi)發(fā)技術(shù)說(shuō)明文檔網(wǎng)絡(luò)軟文推廣網(wǎng)站
  • 北京制作小程序seo的基本步驟是什么
  • 中山精品網(wǎng)站建設(shè)信息昆明網(wǎng)站開(kāi)發(fā)推廣公司
  • centos 網(wǎng)站開(kāi)發(fā)工具怎么做公司網(wǎng)頁(yè)
  • 日本男女做受網(wǎng)站手機(jī)百度如何發(fā)布廣告
  • 專(zhuān)門(mén)做布料的網(wǎng)站外貿(mào)接單平臺(tái)哪個(gè)最好
  • 網(wǎng)站后臺(tái)的用戶名谷歌搜索引擎為什么國(guó)內(nèi)用不了
  • ubuntu做網(wǎng)站服務(wù)器樂(lè)陵seo外包公司
  • 網(wǎng)絡(luò)營(yíng)銷(xiāo)外包是干啥的南寧seo團(tuán)隊(duì)哪家好
  • 河南省新聞出版學(xué)校怎么樣全網(wǎng)優(yōu)化哪家好
  • 網(wǎng)站系統(tǒng)重要性長(zhǎng)沙百度網(wǎng)站優(yōu)化
  • 網(wǎng)站建設(shè) 源美設(shè)計(jì)seo合作代理
  • 織夢(mèng)手機(jī)網(wǎng)站模板上海百度推廣官網(wǎng)
  • ps做網(wǎng)站的效果圖網(wǎng)絡(luò)銷(xiāo)售掙錢(qián)嗎
  • node.js做企業(yè)網(wǎng)站seo的優(yōu)化方案