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

C/C++中獲取重載函數(shù)地址的方法

 更新時(shí)間:2024年04月02日 09:29:14   作者:流星雨愛編程  
函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個(gè)功能類似的同名函數(shù),這 些同名函數(shù)的形參列表不同,常用來處理實(shí)現(xiàn)功能類似數(shù)據(jù)類型不同的問題,本文給大家介紹了C/C++中獲取重載函數(shù)地址的方法,需要的朋友可以參考下

1.現(xiàn)象

函數(shù)重載在C/C++編碼中是非常常見的,但是我們?cè)趕td::bind或std::function綁定函數(shù)地址的時(shí)候,直接取地址,程序編譯就會(huì)報(bào)錯(cuò),示例如下:

class CFunc12345
{
public:
	void func12345(int x) {
		std::cout << x;
	}
	void func12345(double x) {
		std::cout << x;
	}
};
 
void func67890(int x) {
	std::cout << x;
}
void func67890(double x) {
	std::cout << x;
}
 
int main()
{
    CFunc12345 x1;
	auto p = std::bind(&CFunc12345::func12345, x1, std::placeholders::_1); //[1]編譯報(bào)錯(cuò)
	p(14124);
 
    auto p1 = std::bind(&func67890, std::placeholders::_1);  //[2]編譯報(bào)錯(cuò)
	p1(33333333);
 
    std::function<void(int)> p2(&func67890);  //[3]編譯報(bào)錯(cuò)
	p2(33333333);
 
    return 0;
}

上述代碼[1],[2],[3]處都會(huì)出現(xiàn)編譯錯(cuò)誤,那是因?yàn)楹瘮?shù)重載,多個(gè)函數(shù)名相同,找不到該用那個(gè)函數(shù)地址。這個(gè)時(shí)候解決辦法就是人為指定用那個(gè)函數(shù),那么人為指定用那個(gè)函數(shù)有哪些辦法呢?

2.指定參數(shù)取函數(shù)地址

方法如下:

    //方法1:
    CFunc12345 x1;
	using FUNC1 = void (CFunc12345::*)(int);
	FUNC1 func1 = &CFunc12345::func12345;
	auto p1 = std::bind(func1, x1, std::placeholders::_1);
	p1(14124);
 
	using FUNC2 = void(*)(int);
	FUNC2 func2 = &func67890;
	auto p2 = std::bind(func2, std::placeholders::_1);
	p2(14124);
 
	FUNC2 func3 = &func67890;
	std::function<void(int)> p3(func3);
	p3(14124);

從代碼可以看出,就是手動(dòng)指定函數(shù)類型,先取到函數(shù)地址后,再把地址傳入指定的對(duì)象(如std::bind、std::function等)中,避免了std::bind或std::function去判斷函數(shù)類型,從而避免了編譯錯(cuò)誤。

3.利用Qt的類QOverload

QOverload是Qt5中提供的一種用于重載信號(hào)和槽函數(shù)連接的方式。它允許開發(fā)者在使用信號(hào)與槽機(jī)制時(shí),更靈活地處理函數(shù)重載的情況。通過將信號(hào)和槽函數(shù)的參數(shù)類型轉(zhuǎn)換為指定類型,QOverload實(shí)現(xiàn)了對(duì)信號(hào)和槽函數(shù)的類型安全檢查。

在實(shí)際應(yīng)用中,QOverload通過重載調(diào)用QOverload::of,利用它來指定多個(gè)信號(hào)版本中的具體哪種類型參數(shù)。例如,當(dāng)有一個(gè)信號(hào)函數(shù)被重載,具有多個(gè)不同參數(shù)類型的版本時(shí),可以使用QOverload來明確指定要連接的是哪個(gè)版本的信號(hào)函數(shù)。

QOverload的作用就是指定重載函數(shù)中的函數(shù)類型,從它的源碼中可以看出來,源碼如下:

template <typename... Args>
struct QNonConstOverload
{
    template <typename R, typename T>
    Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
 
    template <typename R, typename T>
    static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
};
 
template <typename... Args>
struct QConstOverload
{
    template <typename R, typename T>
    Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
 
    template <typename R, typename T>
    static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
};
 
template <typename... Args>
struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
{
    using QConstOverload<Args...>::of;
    using QConstOverload<Args...>::operator();
    using QNonConstOverload<Args...>::of;
    using QNonConstOverload<Args...>::operator();
 
    template <typename R>
    Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
 
    template <typename R>
    static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
    { return ptr; }
};

顧名思義,模版類QNonConstOverload是取不帶const的類成員函數(shù)的地址的,模版類QConstOverload是取帶const的類成員函數(shù)的地址的,QOverload是取普通函數(shù)地址的,它們之間的關(guān)系如下圖所示:

于是上面編譯錯(cuò)誤的代碼可以修改為:

int main()
{
    //方法2
	CFunc12345 x1;
	auto p = std::bind(QOverload<int>::of(&CFunc12345::func12345), x1, std::placeholders::_1);
	p(14124);
 
	auto p1 = std::bind(QOverload<int>::of(&func67890), std::placeholders::_1);
	p1(33333333);
 
	std::function<void(int)> p2(QOverload<int>::of(&func67890));
	p2(33333333);
 
    return 0;
}

QOverload看似只有裝有Qt環(huán)境才能用,其實(shí)把源碼稍加修改就可以作為標(biāo)準(zhǔn)的C++類來用,修改后的COverload源碼如下所示:

template <typename... Args>
struct CNonConstOverload
{
	template <typename R, typename T>
	auto operator()(R(T::* ptr)(Args...)) const -> decltype(ptr)
	{
		return ptr;
	}
 
	template <typename R, typename T>
	static auto of(R(T::* ptr)(Args...)) -> decltype(ptr)
	{
		return ptr;
	}
};
 
template <typename... Args>
struct CConstOverload
{
	template <typename R, typename T>
	auto operator()(R(T::* ptr)(Args...) const) const -> decltype(ptr)
	{
		return ptr;
	}
 
	template <typename R, typename T>
	static auto of(R(T::* ptr)(Args...) const) -> decltype(ptr)
	{
		return ptr;
	}
};
 
template <typename... Args>
struct COverload : CConstOverload<Args...>, CNonConstOverload<Args...>
{
	using CConstOverload<Args...>::of;
	using CConstOverload<Args...>::operator();
	using CNonConstOverload<Args...>::of;
	using CNonConstOverload<Args...>::operator();
 
	template <typename R>
	auto operator()(R(*ptr)(Args...)) const -> decltype(ptr)
	{
		return ptr;
	}
 
	template <typename R>
	static auto of(R(*ptr)(Args...)) -> decltype(ptr)
	{
		return ptr;
	}
};

QOverload在Qt的信號(hào)槽中也用的比較多。信號(hào)槽連接時(shí),使用基于字符串的語法,可以顯式指定參數(shù)類型。因此,使用重載信號(hào)或槽的哪一個(gè)實(shí)例是明確的。相反,使用基于模版函數(shù)的語法,必須強(qiáng)制轉(zhuǎn)換重載信號(hào)或槽,以告訴編譯器要使用哪個(gè)實(shí)例。

例如,QLCDNumber有三個(gè)版本的display() 槽函數(shù):

1.QLCDNumber::display(int)

2.QLCDNumber::display(double)

3.QLCDNumber::display(QString)

使用信號(hào)QSlider::valueChanged()和QLCDNumber::display(int)連接,可以有如下系列方法:

     auto slider = new QSlider(this);
     auto lcd = new QLCDNumber(this);
 
     // String-based syntax
     connect(slider, SIGNAL(valueChanged(int)),
             lcd, SLOT(display(int)));
 
     // Functor-based syntax, first alternative
     connect(slider, &QSlider::valueChanged,
             lcd, static_cast<void (QLCDNumber::*)(int)>(&QLCDNumber::display));
 
     // Functor-based syntax, second alternative
     void (QLCDNumber::*mySlot)(int) = &QLCDNumber::display;
     connect(slider, &QSlider::valueChanged,
             lcd, mySlot);
 
     // Functor-based syntax, third alternative
     connect(slider, &QSlider::valueChanged,
             lcd, QOverload<int>::of(&QLCDNumber::display));
 
     // Functor-based syntax, fourth alternative (requires C++14)
     connect(slider, &QSlider::valueChanged,
             lcd, qOverload<int>(&QLCDNumber::display));

總的來說,QOverload是一個(gè)強(qiáng)大的工具,它使得在Qt中使用信號(hào)和槽機(jī)制時(shí),處理函數(shù)重載的情況變得更加簡單和直觀。

以上就是C/C++中重載函數(shù)取地址的方法的詳細(xì)內(nèi)容,更多關(guān)于C/C++重載函數(shù)取地址的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解C語言中strcpy()函數(shù)與strncpy()函數(shù)的使用

    詳解C語言中strcpy()函數(shù)與strncpy()函數(shù)的使用

    這篇文章主要介紹了詳解C語言中strcpy()函數(shù)與strncpy()函數(shù)的使用,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-08-08
  • cocos2dx實(shí)現(xiàn)橡皮擦效果以及判斷是否擦除完畢

    cocos2dx實(shí)現(xiàn)橡皮擦效果以及判斷是否擦除完畢

    這篇文章主要為大家詳細(xì)介紹了cocos2dx實(shí)現(xiàn)橡皮擦效果以及判斷是否擦除完畢,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 使用C++制作簡單的web服務(wù)器(續(xù))

    使用C++制作簡單的web服務(wù)器(續(xù))

    本文承接上文《使用C++制作簡單的web服務(wù)器》,把web服務(wù)器做的功能稍微強(qiáng)大些,主要增加的功能是從文件中讀取網(wǎng)頁并返回給客戶端,而不是把網(wǎng)頁代碼寫死在代碼中,有需要的小伙伴來參考下吧。
    2015-03-03
  • C/C++中獲取數(shù)組長度的方法示例

    C/C++中獲取數(shù)組長度的方法示例

    這篇文章主要介紹了C/C++中獲取數(shù)組長度的方法,很實(shí)用的一種方法,需要的朋友可以參考下
    2014-08-08
  • c++標(biāo)準(zhǔn)輸入輸出流關(guān)系的前世今生

    c++標(biāo)準(zhǔn)輸入輸出流關(guān)系的前世今生

    這篇文章主要給大家介紹了關(guān)于c++標(biāo)準(zhǔn)輸入輸出流關(guān)系的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C++ 遍歷某個(gè)文件夾下所有文件的方法步驟

    C++ 遍歷某個(gè)文件夾下所有文件的方法步驟

    這篇文章主要介紹了C++ 遍歷某個(gè)文件夾下所有文件的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 解析使用C++編寫無錯(cuò)代碼的方法技巧

    解析使用C++編寫無錯(cuò)代碼的方法技巧

    本篇文章是對(duì)使用C++編寫無錯(cuò)代碼的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 深入Windows下的回車是回車換行(\r\n)還是換行回車(\n\r)的詳解

    深入Windows下的回車是回車換行(\r\n)還是換行回車(\n\r)的詳解

    本篇文章對(duì)Windows下的回車是回車換行(\r\n)還是換行回車(\n\r)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++抽象基類講解

    C++抽象基類講解

    這篇文章主要介紹了C++抽象基類講解,象基類abstract base class簡稱ABC,C++實(shí)現(xiàn)繼承的時(shí)候,需要保證派生類和基類之間是一種is-a的關(guān)系。在大多數(shù)時(shí)刻,這樣的關(guān)系是沒有問題的,然而在一些特殊的情況可能會(huì)遇到問題,下面來看看文章的具體介紹吧
    2022-01-01
  • Conan中的C/C++的依賴管理

    Conan中的C/C++的依賴管理

    C/C++與Java、Python都有庫依賴問題,但是C/C++語言沒有自帶的包管理機(jī)制,也許是因?yàn)镃/C++更多的應(yīng)用于系統(tǒng)程序領(lǐng)域,Java、Python更多用于應(yīng)用程序領(lǐng)域,對(duì)快速開發(fā)和部署要求更高,今天通過本文給大家介紹Conan中的C/C++的依賴管理,感興趣的朋友一起看看吧
    2023-01-01

最新評(píng)論